diff --git a/.release-please-manifest.json b/.release-please-manifest.json index abeb3ccf..88e4c443 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.19.2" + ".": "4.20.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 606cf6c2..04c1236b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 136 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-7cc3e4b60242e0446ddcf3cd170b5694842c0a54a13572df20a4e91a75d6b189.yml -openapi_spec_hash: 5992603d99d6100bad823c6932a4bd06 -config_hash: 627f8592c19dfb77f91ffbec2a057c3a +configured_endpoints: 138 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-cba470b0c221bcfbe2e8bf51276292285a60a05a4c0b47f5f741706adf1205fc.yml +openapi_spec_hash: c9f1b73fb32f39243d9d95a667ea3341 +config_hash: 6025fdbfe31c3b2d57a71f9885d37294 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc8a176..5e884990 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 4.20.0 (2026-07-09) + +Full Changelog: [v4.19.2...v4.20.0](https://github.com/trycourier/courier-java/compare/v4.19.2...v4.20.0) + +### Features + +* Add bulk user preference upsert and replace endpoints ([e119feb](https://github.com/trycourier/courier-java/commit/e119feb43eceb25d6599d9cb6c9f83178c184e64)) +* Preferences v3 REST fields: section/topic description + publish body ([30e226b](https://github.com/trycourier/courier-java/commit/30e226b6693d399cb83c0e3ffbbe77d2b851339b)) + ## 4.19.2 (2026-07-09) Full Changelog: [v4.19.1...v4.19.2](https://github.com/trycourier/courier-java/compare/v4.19.1...v4.19.2) diff --git a/build.gradle.kts b/build.gradle.kts index b6360b74..f564a9d3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.courier" - version = "4.19.2" // x-release-please-version + version = "4.20.0" // x-release-please-version } subprojects { diff --git a/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/BulkPreferenceTopic.kt b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/BulkPreferenceTopic.kt new file mode 100644 index 00000000..8338f96d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/BulkPreferenceTopic.kt @@ -0,0 +1,461 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** A single topic override echoed in a bulk preference response. */ +class BulkPreferenceTopic +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val customRouting: JsonField>, + private val hasCustomRouting: JsonField, + private val status: JsonField, + private val topicId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("custom_routing") + @ExcludeMissing + customRouting: JsonField> = JsonMissing.of(), + @JsonProperty("has_custom_routing") + @ExcludeMissing + hasCustomRouting: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), + ) : this(customRouting, hasCustomRouting, status, topicId, mutableMapOf()) + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun customRouting(): List = customRouting.getRequired("custom_routing") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun hasCustomRouting(): Boolean = hasCustomRouting.getRequired("has_custom_routing") + + /** + * The applied subscription status. Echoes the requested value, so it is always OPTED_IN or + * OPTED_OUT. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun status(): Status = status.getRequired("status") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topicId(): String = topicId.getRequired("topic_id") + + /** + * Returns the raw JSON value of [customRouting]. + * + * Unlike [customRouting], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("custom_routing") + @ExcludeMissing + fun _customRouting(): JsonField> = customRouting + + /** + * Returns the raw JSON value of [hasCustomRouting]. + * + * Unlike [hasCustomRouting], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("has_custom_routing") + @ExcludeMissing + fun _hasCustomRouting(): JsonField = hasCustomRouting + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BulkPreferenceTopic]. + * + * The following fields are required: + * ```java + * .customRouting() + * .hasCustomRouting() + * .status() + * .topicId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BulkPreferenceTopic]. */ + class Builder internal constructor() { + + private var customRouting: JsonField>? = null + private var hasCustomRouting: JsonField? = null + private var status: JsonField? = null + private var topicId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(bulkPreferenceTopic: BulkPreferenceTopic) = apply { + customRouting = bulkPreferenceTopic.customRouting.map { it.toMutableList() } + hasCustomRouting = bulkPreferenceTopic.hasCustomRouting + status = bulkPreferenceTopic.status + topicId = bulkPreferenceTopic.topicId + additionalProperties = bulkPreferenceTopic.additionalProperties.toMutableMap() + } + + fun customRouting(customRouting: List) = + customRouting(JsonField.of(customRouting)) + + /** + * Sets [Builder.customRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.customRouting] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun customRouting(customRouting: JsonField>) = apply { + this.customRouting = customRouting.map { it.toMutableList() } + } + + /** + * Adds a single [ChannelClassification] to [Builder.customRouting]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCustomRouting(customRouting: ChannelClassification) = apply { + this.customRouting = + (this.customRouting ?: JsonField.of(mutableListOf())).also { + checkKnown("customRouting", it).add(customRouting) + } + } + + fun hasCustomRouting(hasCustomRouting: Boolean) = + hasCustomRouting(JsonField.of(hasCustomRouting)) + + /** + * Sets [Builder.hasCustomRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.hasCustomRouting] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun hasCustomRouting(hasCustomRouting: JsonField) = apply { + this.hasCustomRouting = hasCustomRouting + } + + /** + * The applied subscription status. Echoes the requested value, so it is always OPTED_IN or + * OPTED_OUT. + */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BulkPreferenceTopic]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .customRouting() + * .hasCustomRouting() + * .status() + * .topicId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BulkPreferenceTopic = + BulkPreferenceTopic( + checkRequired("customRouting", customRouting).map { it.toImmutable() }, + checkRequired("hasCustomRouting", hasCustomRouting), + checkRequired("status", status), + checkRequired("topicId", topicId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BulkPreferenceTopic = apply { + if (validated) { + return@apply + } + + customRouting().forEach { it.validate() } + hasCustomRouting() + status().validate() + topicId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (customRouting.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (hasCustomRouting.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (topicId.asKnown().isPresent) 1 else 0) + + /** + * The applied subscription status. Echoes the requested value, so it is always OPTED_IN or + * OPTED_OUT. + */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val OPTED_IN = of("OPTED_IN") + + @JvmField val OPTED_OUT = of("OPTED_OUT") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + OPTED_IN, + OPTED_OUT, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + OPTED_IN, + OPTED_OUT, + /** An enum member indicating that [Status] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + OPTED_IN -> Value.OPTED_IN + OPTED_OUT -> Value.OPTED_OUT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + OPTED_IN -> Known.OPTED_IN + OPTED_OUT -> Known.OPTED_OUT + else -> throw CourierInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { CourierInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BulkPreferenceTopic && + customRouting == other.customRouting && + hasCustomRouting == other.hasCustomRouting && + status == other.status && + topicId == other.topicId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(customRouting, hasCustomRouting, status, topicId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BulkPreferenceTopic{customRouting=$customRouting, hasCustomRouting=$hasCustomRouting, status=$status, topicId=$topicId, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParams.kt new file mode 100644 index 00000000..042a6500 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParams.kt @@ -0,0 +1,974 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Replace a user's complete set of preference overrides in a single request. The topics in the + * request body become the recipient's entire set of overrides: listed topics are created or + * updated, and every existing override that is not included in the body is reset to its topic + * default. Submitting an empty `topics` array is a valid clear-all that resets every existing + * override. + * + * This operation is validation-atomic (all-or-nothing): structural validation fails fast with a + * single `400`, and if any topic is semantically invalid (an unknown topic, a `REQUIRED` topic that + * cannot be opted out, or a custom routing request that is not available on the workspace's plan) + * the request returns a single `400` aggregating every failure in `errors` and writes nothing. On + * success it returns `200` with `items` (the complete resulting override set) and `deleted` (the + * ids of the overrides that were reset to default). + * + * Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is returned in + * Courier's canonical topic id form, regardless of the form supplied in the request. + */ +class PreferenceBulkReplaceParams +private constructor( + private val userId: String?, + private val tenantId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** Update the preferences of a user for this specific tenant context. */ + fun tenantId(): Optional = Optional.ofNullable(tenantId) + + /** + * The complete set of topic overrides for the user. Up to 50 topics may be provided. Any + * existing override not listed here is reset to its topic default; an empty array resets every + * existing override. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topics(): List = body.topics() + + /** + * Returns the raw JSON value of [topics]. + * + * Unlike [topics], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _topics(): JsonField> = body._topics() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PreferenceBulkReplaceParams]. + * + * The following fields are required: + * ```java + * .topics() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PreferenceBulkReplaceParams]. */ + class Builder internal constructor() { + + private var userId: String? = null + private var tenantId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(preferenceBulkReplaceParams: PreferenceBulkReplaceParams) = apply { + userId = preferenceBulkReplaceParams.userId + tenantId = preferenceBulkReplaceParams.tenantId + body = preferenceBulkReplaceParams.body.toBuilder() + additionalHeaders = preferenceBulkReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = preferenceBulkReplaceParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** Update the preferences of a user for this specific tenant context. */ + fun tenantId(tenantId: String?) = apply { this.tenantId = tenantId } + + /** Alias for calling [Builder.tenantId] with `tenantId.orElse(null)`. */ + fun tenantId(tenantId: Optional) = tenantId(tenantId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [topics] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * The complete set of topic overrides for the user. Up to 50 topics may be provided. Any + * existing override not listed here is reset to its topic default; an empty array resets + * every existing override. + */ + fun topics(topics: List) = apply { body.topics(topics) } + + /** + * Sets [Builder.topics] to an arbitrary JSON value. + * + * You should usually call [Builder.topics] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun topics(topics: JsonField>) = apply { body.topics(topics) } + + /** + * Adds a single [Topic] to [topics]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTopic(topic: Topic) = apply { body.addTopic(topic) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [PreferenceBulkReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .topics() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PreferenceBulkReplaceParams = + PreferenceBulkReplaceParams( + userId, + tenantId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + tenantId?.let { put("tenant_id", it) } + putAll(additionalQueryParams) + } + .build() + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val topics: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("topics") + @ExcludeMissing + topics: JsonField> = JsonMissing.of() + ) : this(topics, mutableMapOf()) + + /** + * The complete set of topic overrides for the user. Up to 50 topics may be provided. Any + * existing override not listed here is reset to its topic default; an empty array resets + * every existing override. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topics(): List = topics.getRequired("topics") + + /** + * Returns the raw JSON value of [topics]. + * + * Unlike [topics], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topics") @ExcludeMissing fun _topics(): JsonField> = topics + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .topics() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var topics: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + topics = body.topics.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * The complete set of topic overrides for the user. Up to 50 topics may be provided. + * Any existing override not listed here is reset to its topic default; an empty array + * resets every existing override. + */ + fun topics(topics: List) = topics(JsonField.of(topics)) + + /** + * Sets [Builder.topics] to an arbitrary JSON value. + * + * You should usually call [Builder.topics] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topics(topics: JsonField>) = apply { + this.topics = topics.map { it.toMutableList() } + } + + /** + * Adds a single [Topic] to [topics]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTopic(topic: Topic) = apply { + topics = + (topics ?: JsonField.of(mutableListOf())).also { + checkKnown("topics", it).add(topic) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .topics() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("topics", topics).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Body = apply { + if (validated) { + return@apply + } + + topics().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (topics.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + topics == other.topics && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(topics, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{topics=$topics, additionalProperties=$additionalProperties}" + } + + class Topic + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val status: JsonField, + private val topicId: JsonField, + private val customRouting: JsonField>, + private val hasCustomRouting: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), + @JsonProperty("custom_routing") + @ExcludeMissing + customRouting: JsonField> = JsonMissing.of(), + @JsonProperty("has_custom_routing") + @ExcludeMissing + hasCustomRouting: JsonField = JsonMissing.of(), + ) : this(status, topicId, customRouting, hasCustomRouting, mutableMapOf()) + + /** + * The subscription status to apply for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun status(): Status = status.getRequired("status") + + /** + * A unique identifier associated with a subscription topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topicId(): String = topicId.getRequired("topic_id") + + /** + * The channels a user has chosen to receive notifications through for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun customRouting(): Optional> = + customRouting.getOptional("custom_routing") + + /** + * Whether the recipient has chosen specific delivery channels for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hasCustomRouting(): Optional = + hasCustomRouting.getOptional("has_custom_routing") + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + /** + * Returns the raw JSON value of [customRouting]. + * + * Unlike [customRouting], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("custom_routing") + @ExcludeMissing + fun _customRouting(): JsonField> = customRouting + + /** + * Returns the raw JSON value of [hasCustomRouting]. + * + * Unlike [hasCustomRouting], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("has_custom_routing") + @ExcludeMissing + fun _hasCustomRouting(): JsonField = hasCustomRouting + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Topic]. + * + * The following fields are required: + * ```java + * .status() + * .topicId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Topic]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var topicId: JsonField? = null + private var customRouting: JsonField>? = null + private var hasCustomRouting: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(topic: Topic) = apply { + status = topic.status + topicId = topic.topicId + customRouting = topic.customRouting.map { it.toMutableList() } + hasCustomRouting = topic.hasCustomRouting + additionalProperties = topic.additionalProperties.toMutableMap() + } + + /** The subscription status to apply for this topic. */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** A unique identifier associated with a subscription topic. */ + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + /** The channels a user has chosen to receive notifications through for this topic. */ + fun customRouting(customRouting: List) = + customRouting(JsonField.of(customRouting)) + + /** + * Sets [Builder.customRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.customRouting] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun customRouting(customRouting: JsonField>) = apply { + this.customRouting = customRouting.map { it.toMutableList() } + } + + /** + * Adds a single [ChannelClassification] to [Builder.customRouting]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCustomRouting(customRouting: ChannelClassification) = apply { + this.customRouting = + (this.customRouting ?: JsonField.of(mutableListOf())).also { + checkKnown("customRouting", it).add(customRouting) + } + } + + /** Whether the recipient has chosen specific delivery channels for this topic. */ + fun hasCustomRouting(hasCustomRouting: Boolean) = + hasCustomRouting(JsonField.of(hasCustomRouting)) + + /** + * Sets [Builder.hasCustomRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.hasCustomRouting] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun hasCustomRouting(hasCustomRouting: JsonField) = apply { + this.hasCustomRouting = hasCustomRouting + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Topic]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * .topicId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Topic = + Topic( + checkRequired("status", status), + checkRequired("topicId", topicId), + (customRouting ?: JsonMissing.of()).map { it.toImmutable() }, + hasCustomRouting, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Topic = apply { + if (validated) { + return@apply + } + + status().validate() + topicId() + customRouting().ifPresent { it.forEach { it.validate() } } + hasCustomRouting() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (topicId.asKnown().isPresent) 1 else 0) + + (customRouting.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (hasCustomRouting.asKnown().isPresent) 1 else 0) + + /** The subscription status to apply for this topic. */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val OPTED_IN = of("OPTED_IN") + + @JvmField val OPTED_OUT = of("OPTED_OUT") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + OPTED_IN, + OPTED_OUT, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + OPTED_IN, + OPTED_OUT, + /** + * An enum member indicating that [Status] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + OPTED_IN -> Value.OPTED_IN + OPTED_OUT -> Value.OPTED_OUT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + OPTED_IN -> Known.OPTED_IN + OPTED_OUT -> Known.OPTED_OUT + else -> throw CourierInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Topic && + status == other.status && + topicId == other.topicId && + customRouting == other.customRouting && + hasCustomRouting == other.hasCustomRouting && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(status, topicId, customRouting, hasCustomRouting, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Topic{status=$status, topicId=$topicId, customRouting=$customRouting, hasCustomRouting=$hasCustomRouting, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PreferenceBulkReplaceParams && + userId == other.userId && + tenantId == other.tenantId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, tenantId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "PreferenceBulkReplaceParams{userId=$userId, tenantId=$tenantId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponse.kt new file mode 100644 index 00000000..fdd63670 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponse.kt @@ -0,0 +1,257 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +class PreferenceBulkReplaceResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val deleted: JsonField>, + private val items: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("deleted") + @ExcludeMissing + deleted: JsonField> = JsonMissing.of(), + @JsonProperty("items") + @ExcludeMissing + items: JsonField> = JsonMissing.of(), + ) : this(deleted, items, mutableMapOf()) + + /** + * The ids of the overrides that were reset to their topic default. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun deleted(): List = deleted.getRequired("deleted") + + /** + * The complete resulting set of topic overrides for the user. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun items(): List = items.getRequired("items") + + /** + * Returns the raw JSON value of [deleted]. + * + * Unlike [deleted], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted") @ExcludeMissing fun _deleted(): JsonField> = deleted + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") + @ExcludeMissing + fun _items(): JsonField> = items + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [PreferenceBulkReplaceResponse]. + * + * The following fields are required: + * ```java + * .deleted() + * .items() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PreferenceBulkReplaceResponse]. */ + class Builder internal constructor() { + + private var deleted: JsonField>? = null + private var items: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(preferenceBulkReplaceResponse: PreferenceBulkReplaceResponse) = apply { + deleted = preferenceBulkReplaceResponse.deleted.map { it.toMutableList() } + items = preferenceBulkReplaceResponse.items.map { it.toMutableList() } + additionalProperties = preferenceBulkReplaceResponse.additionalProperties.toMutableMap() + } + + /** The ids of the overrides that were reset to their topic default. */ + fun deleted(deleted: List) = deleted(JsonField.of(deleted)) + + /** + * Sets [Builder.deleted] to an arbitrary JSON value. + * + * You should usually call [Builder.deleted] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun deleted(deleted: JsonField>) = apply { + this.deleted = deleted.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.deleted]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDeleted(deleted: String) = apply { + this.deleted = + (this.deleted ?: JsonField.of(mutableListOf())).also { + checkKnown("deleted", it).add(deleted) + } + } + + /** The complete resulting set of topic overrides for the user. */ + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [BulkPreferenceTopic] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: BulkPreferenceTopic) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PreferenceBulkReplaceResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .deleted() + * .items() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PreferenceBulkReplaceResponse = + PreferenceBulkReplaceResponse( + checkRequired("deleted", deleted).map { it.toImmutable() }, + checkRequired("items", items).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): PreferenceBulkReplaceResponse = apply { + if (validated) { + return@apply + } + + deleted() + items().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (deleted.asKnown().getOrNull()?.size ?: 0) + + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PreferenceBulkReplaceResponse && + deleted == other.deleted && + items == other.items && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(deleted, items, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PreferenceBulkReplaceResponse{deleted=$deleted, items=$items, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParams.kt new file mode 100644 index 00000000..3f3b17a2 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParams.kt @@ -0,0 +1,967 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.Enum +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.Params +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.http.Headers +import com.courier.core.http.QueryParams +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Additively create or update a user's preferences for one or more subscription topics in a single + * request. Only the topics included in the request body are created or updated; any existing + * overrides for topics not listed are left untouched. + * + * Structural validation of the request body fails fast with a single `400`. Beyond that, each topic + * is processed independently (partial-success, not all-or-nothing): valid topics are written and + * returned in `items`, while topics that cannot be applied are collected in `errors` with a + * per-topic `reason` (for example an unknown topic, a `REQUIRED` topic that cannot be opted out, a + * custom routing request that is not available on the workspace's plan, or a write failure). The + * request therefore returns `200` with both lists whenever the body is structurally valid. + * + * Every `topic_id` in the response — in both `items` and `errors` — is returned in Courier's + * canonical topic id form, regardless of the form supplied in the request. + */ +class PreferenceBulkUpdateParams +private constructor( + private val userId: String?, + private val tenantId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun userId(): Optional = Optional.ofNullable(userId) + + /** Update the preferences of a user for this specific tenant context. */ + fun tenantId(): Optional = Optional.ofNullable(tenantId) + + /** + * The topics to create or update. Between 1 and 50 topics may be provided in a single request. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topics(): List = body.topics() + + /** + * Returns the raw JSON value of [topics]. + * + * Unlike [topics], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _topics(): JsonField> = body._topics() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PreferenceBulkUpdateParams]. + * + * The following fields are required: + * ```java + * .topics() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PreferenceBulkUpdateParams]. */ + class Builder internal constructor() { + + private var userId: String? = null + private var tenantId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(preferenceBulkUpdateParams: PreferenceBulkUpdateParams) = apply { + userId = preferenceBulkUpdateParams.userId + tenantId = preferenceBulkUpdateParams.tenantId + body = preferenceBulkUpdateParams.body.toBuilder() + additionalHeaders = preferenceBulkUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = preferenceBulkUpdateParams.additionalQueryParams.toBuilder() + } + + fun userId(userId: String?) = apply { this.userId = userId } + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** Update the preferences of a user for this specific tenant context. */ + fun tenantId(tenantId: String?) = apply { this.tenantId = tenantId } + + /** Alias for calling [Builder.tenantId] with `tenantId.orElse(null)`. */ + fun tenantId(tenantId: Optional) = tenantId(tenantId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [topics] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * The topics to create or update. Between 1 and 50 topics may be provided in a single + * request. + */ + fun topics(topics: List) = apply { body.topics(topics) } + + /** + * Sets [Builder.topics] to an arbitrary JSON value. + * + * You should usually call [Builder.topics] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun topics(topics: JsonField>) = apply { body.topics(topics) } + + /** + * Adds a single [Topic] to [topics]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTopic(topic: Topic) = apply { body.addTopic(topic) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [PreferenceBulkUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .topics() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PreferenceBulkUpdateParams = + PreferenceBulkUpdateParams( + userId, + tenantId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> userId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + tenantId?.let { put("tenant_id", it) } + putAll(additionalQueryParams) + } + .build() + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val topics: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("topics") + @ExcludeMissing + topics: JsonField> = JsonMissing.of() + ) : this(topics, mutableMapOf()) + + /** + * The topics to create or update. Between 1 and 50 topics may be provided in a single + * request. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topics(): List = topics.getRequired("topics") + + /** + * Returns the raw JSON value of [topics]. + * + * Unlike [topics], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topics") @ExcludeMissing fun _topics(): JsonField> = topics + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .topics() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var topics: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + topics = body.topics.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * The topics to create or update. Between 1 and 50 topics may be provided in a single + * request. + */ + fun topics(topics: List) = topics(JsonField.of(topics)) + + /** + * Sets [Builder.topics] to an arbitrary JSON value. + * + * You should usually call [Builder.topics] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topics(topics: JsonField>) = apply { + this.topics = topics.map { it.toMutableList() } + } + + /** + * Adds a single [Topic] to [topics]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTopic(topic: Topic) = apply { + topics = + (topics ?: JsonField.of(mutableListOf())).also { + checkKnown("topics", it).add(topic) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .topics() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("topics", topics).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Body = apply { + if (validated) { + return@apply + } + + topics().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (topics.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + topics == other.topics && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(topics, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{topics=$topics, additionalProperties=$additionalProperties}" + } + + class Topic + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val status: JsonField, + private val topicId: JsonField, + private val customRouting: JsonField>, + private val hasCustomRouting: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), + @JsonProperty("custom_routing") + @ExcludeMissing + customRouting: JsonField> = JsonMissing.of(), + @JsonProperty("has_custom_routing") + @ExcludeMissing + hasCustomRouting: JsonField = JsonMissing.of(), + ) : this(status, topicId, customRouting, hasCustomRouting, mutableMapOf()) + + /** + * The subscription status to apply for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun status(): Status = status.getRequired("status") + + /** + * A unique identifier associated with a subscription topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topicId(): String = topicId.getRequired("topic_id") + + /** + * The channels a user has chosen to receive notifications through for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun customRouting(): Optional> = + customRouting.getOptional("custom_routing") + + /** + * Whether the recipient has chosen specific delivery channels for this topic. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hasCustomRouting(): Optional = + hasCustomRouting.getOptional("has_custom_routing") + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + /** + * Returns the raw JSON value of [customRouting]. + * + * Unlike [customRouting], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("custom_routing") + @ExcludeMissing + fun _customRouting(): JsonField> = customRouting + + /** + * Returns the raw JSON value of [hasCustomRouting]. + * + * Unlike [hasCustomRouting], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("has_custom_routing") + @ExcludeMissing + fun _hasCustomRouting(): JsonField = hasCustomRouting + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Topic]. + * + * The following fields are required: + * ```java + * .status() + * .topicId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Topic]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var topicId: JsonField? = null + private var customRouting: JsonField>? = null + private var hasCustomRouting: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(topic: Topic) = apply { + status = topic.status + topicId = topic.topicId + customRouting = topic.customRouting.map { it.toMutableList() } + hasCustomRouting = topic.hasCustomRouting + additionalProperties = topic.additionalProperties.toMutableMap() + } + + /** The subscription status to apply for this topic. */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** A unique identifier associated with a subscription topic. */ + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + /** The channels a user has chosen to receive notifications through for this topic. */ + fun customRouting(customRouting: List) = + customRouting(JsonField.of(customRouting)) + + /** + * Sets [Builder.customRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.customRouting] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun customRouting(customRouting: JsonField>) = apply { + this.customRouting = customRouting.map { it.toMutableList() } + } + + /** + * Adds a single [ChannelClassification] to [Builder.customRouting]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCustomRouting(customRouting: ChannelClassification) = apply { + this.customRouting = + (this.customRouting ?: JsonField.of(mutableListOf())).also { + checkKnown("customRouting", it).add(customRouting) + } + } + + /** Whether the recipient has chosen specific delivery channels for this topic. */ + fun hasCustomRouting(hasCustomRouting: Boolean) = + hasCustomRouting(JsonField.of(hasCustomRouting)) + + /** + * Sets [Builder.hasCustomRouting] to an arbitrary JSON value. + * + * You should usually call [Builder.hasCustomRouting] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun hasCustomRouting(hasCustomRouting: JsonField) = apply { + this.hasCustomRouting = hasCustomRouting + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Topic]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * .topicId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Topic = + Topic( + checkRequired("status", status), + checkRequired("topicId", topicId), + (customRouting ?: JsonMissing.of()).map { it.toImmutable() }, + hasCustomRouting, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Topic = apply { + if (validated) { + return@apply + } + + status().validate() + topicId() + customRouting().ifPresent { it.forEach { it.validate() } } + hasCustomRouting() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (topicId.asKnown().isPresent) 1 else 0) + + (customRouting.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (hasCustomRouting.asKnown().isPresent) 1 else 0) + + /** The subscription status to apply for this topic. */ + class Status @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val OPTED_IN = of("OPTED_IN") + + @JvmField val OPTED_OUT = of("OPTED_OUT") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + OPTED_IN, + OPTED_OUT, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + OPTED_IN, + OPTED_OUT, + /** + * An enum member indicating that [Status] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + OPTED_IN -> Value.OPTED_IN + OPTED_OUT -> Value.OPTED_OUT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws CourierInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + OPTED_IN -> Known.OPTED_IN + OPTED_OUT -> Known.OPTED_OUT + else -> throw CourierInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws CourierInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + CourierInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Topic && + status == other.status && + topicId == other.topicId && + customRouting == other.customRouting && + hasCustomRouting == other.hasCustomRouting && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(status, topicId, customRouting, hasCustomRouting, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Topic{status=$status, topicId=$topicId, customRouting=$customRouting, hasCustomRouting=$hasCustomRouting, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PreferenceBulkUpdateParams && + userId == other.userId && + tenantId == other.tenantId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(userId, tenantId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "PreferenceBulkUpdateParams{userId=$userId, tenantId=$tenantId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponse.kt new file mode 100644 index 00000000..583f8d5d --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponse.kt @@ -0,0 +1,458 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.core.checkKnown +import com.courier.core.checkRequired +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +class PreferenceBulkUpdateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val errors: JsonField>, + private val items: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("errors") @ExcludeMissing errors: JsonField> = JsonMissing.of(), + @JsonProperty("items") + @ExcludeMissing + items: JsonField> = JsonMissing.of(), + ) : this(errors, items, mutableMapOf()) + + /** + * The topics that could not be applied, each with a reason. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun errors(): List = errors.getRequired("errors") + + /** + * The topics that were successfully created or updated. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun items(): List = items.getRequired("items") + + /** + * Returns the raw JSON value of [errors]. + * + * Unlike [errors], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("errors") @ExcludeMissing fun _errors(): JsonField> = errors + + /** + * Returns the raw JSON value of [items]. + * + * Unlike [items], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("items") + @ExcludeMissing + fun _items(): JsonField> = items + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PreferenceBulkUpdateResponse]. + * + * The following fields are required: + * ```java + * .errors() + * .items() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PreferenceBulkUpdateResponse]. */ + class Builder internal constructor() { + + private var errors: JsonField>? = null + private var items: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(preferenceBulkUpdateResponse: PreferenceBulkUpdateResponse) = apply { + errors = preferenceBulkUpdateResponse.errors.map { it.toMutableList() } + items = preferenceBulkUpdateResponse.items.map { it.toMutableList() } + additionalProperties = preferenceBulkUpdateResponse.additionalProperties.toMutableMap() + } + + /** The topics that could not be applied, each with a reason. */ + fun errors(errors: List) = errors(JsonField.of(errors)) + + /** + * Sets [Builder.errors] to an arbitrary JSON value. + * + * You should usually call [Builder.errors] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun errors(errors: JsonField>) = apply { + this.errors = errors.map { it.toMutableList() } + } + + /** + * Adds a single [Error] to [errors]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addError(error: Error) = apply { + errors = + (errors ?: JsonField.of(mutableListOf())).also { + checkKnown("errors", it).add(error) + } + } + + /** The topics that were successfully created or updated. */ + fun items(items: List) = items(JsonField.of(items)) + + /** + * Sets [Builder.items] to an arbitrary JSON value. + * + * You should usually call [Builder.items] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun items(items: JsonField>) = apply { + this.items = items.map { it.toMutableList() } + } + + /** + * Adds a single [BulkPreferenceTopic] to [items]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addItem(item: BulkPreferenceTopic) = apply { + items = + (items ?: JsonField.of(mutableListOf())).also { checkKnown("items", it).add(item) } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PreferenceBulkUpdateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .errors() + * .items() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PreferenceBulkUpdateResponse = + PreferenceBulkUpdateResponse( + checkRequired("errors", errors).map { it.toImmutable() }, + checkRequired("items", items).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): PreferenceBulkUpdateResponse = apply { + if (validated) { + return@apply + } + + errors().forEach { it.validate() } + items().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (errors.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + /** A single topic that could not be applied in a bulk preference request. */ + class Error + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val reason: JsonField, + private val topicId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + @JsonProperty("topic_id") @ExcludeMissing topicId: JsonField = JsonMissing.of(), + ) : this(reason, topicId, mutableMapOf()) + + /** + * A human-readable explanation of why the topic could not be applied. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun reason(): String = reason.getRequired("reason") + + /** + * @throws CourierInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun topicId(): String = topicId.getRequired("topic_id") + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + /** + * Returns the raw JSON value of [topicId]. + * + * Unlike [topicId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topic_id") @ExcludeMissing fun _topicId(): JsonField = topicId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Error]. + * + * The following fields are required: + * ```java + * .reason() + * .topicId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Error]. */ + class Builder internal constructor() { + + private var reason: JsonField? = null + private var topicId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(error: Error) = apply { + reason = error.reason + topicId = error.topicId + additionalProperties = error.additionalProperties.toMutableMap() + } + + /** A human-readable explanation of why the topic could not be applied. */ + fun reason(reason: String) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + fun topicId(topicId: String) = topicId(JsonField.of(topicId)) + + /** + * Sets [Builder.topicId] to an arbitrary JSON value. + * + * You should usually call [Builder.topicId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topicId(topicId: JsonField) = apply { this.topicId = topicId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Error]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .reason() + * .topicId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Error = + Error( + checkRequired("reason", reason), + checkRequired("topicId", topicId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Error = apply { + if (validated) { + return@apply + } + + reason() + topicId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (reason.asKnown().isPresent) 1 else 0) + (if (topicId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Error && + reason == other.reason && + topicId == other.topicId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(reason, topicId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Error{reason=$reason, topicId=$topicId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PreferenceBulkUpdateResponse && + errors == other.errors && + items == other.items && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(errors, items, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PreferenceBulkUpdateResponse{errors=$errors, items=$items, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequest.kt new file mode 100644 index 00000000..1fac563f --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequest.kt @@ -0,0 +1,262 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.workspacepreferences + +import com.courier.core.ExcludeMissing +import com.courier.core.JsonField +import com.courier.core.JsonMissing +import com.courier.core.JsonValue +import com.courier.errors.CourierInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Optional page metadata to apply when publishing the workspace's preferences page. All fields are + * optional; omitted fields fall back to the page defaults (and the workspace default brand). + */ +class PublishPreferencesRequest +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val brandId: JsonField, + private val description: JsonField, + private val heading: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("brand_id") @ExcludeMissing brandId: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("heading") @ExcludeMissing heading: JsonField = JsonMissing.of(), + ) : this(brandId, description, heading, mutableMapOf()) + + /** + * Brand for the hosted page - "default" (workspace default brand), "none" (no brand), or a + * specific brand id. Defaults to "default". + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brandId(): Optional = brandId.getOptional("brand_id") + + /** + * Description shown under the heading on the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * Heading shown at the top of the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun heading(): Optional = heading.getOptional("heading") + + /** + * Returns the raw JSON value of [brandId]. + * + * Unlike [brandId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand_id") @ExcludeMissing fun _brandId(): JsonField = brandId + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [heading]. + * + * Unlike [heading], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("heading") @ExcludeMissing fun _heading(): JsonField = heading + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PublishPreferencesRequest]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PublishPreferencesRequest]. */ + class Builder internal constructor() { + + private var brandId: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var heading: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(publishPreferencesRequest: PublishPreferencesRequest) = apply { + brandId = publishPreferencesRequest.brandId + description = publishPreferencesRequest.description + heading = publishPreferencesRequest.heading + additionalProperties = publishPreferencesRequest.additionalProperties.toMutableMap() + } + + /** + * Brand for the hosted page - "default" (workspace default brand), "none" (no brand), or a + * specific brand id. Defaults to "default". + */ + fun brandId(brandId: String?) = brandId(JsonField.ofNullable(brandId)) + + /** Alias for calling [Builder.brandId] with `brandId.orElse(null)`. */ + fun brandId(brandId: Optional) = brandId(brandId.getOrNull()) + + /** + * Sets [Builder.brandId] to an arbitrary JSON value. + * + * You should usually call [Builder.brandId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun brandId(brandId: JsonField) = apply { this.brandId = brandId } + + /** Description shown under the heading on the hosted preferences page. */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + + /** Heading shown at the top of the hosted preferences page. */ + fun heading(heading: String?) = heading(JsonField.ofNullable(heading)) + + /** Alias for calling [Builder.heading] with `heading.orElse(null)`. */ + fun heading(heading: Optional) = heading(heading.getOrNull()) + + /** + * Sets [Builder.heading] to an arbitrary JSON value. + * + * You should usually call [Builder.heading] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun heading(heading: JsonField) = apply { this.heading = heading } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PublishPreferencesRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PublishPreferencesRequest = + PublishPreferencesRequest( + brandId, + description, + heading, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws CourierInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): PublishPreferencesRequest = apply { + if (validated) { + return@apply + } + + brandId() + description() + heading() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: CourierInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (brandId.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + + (if (heading.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PublishPreferencesRequest && + brandId == other.brandId && + description == other.description && + heading == other.heading && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(brandId, description, heading, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PublishPreferencesRequest{brandId=$brandId, description=$description, heading=$heading, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequest.kt index c4a7c5b3..435143ec 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequest.kt @@ -25,6 +25,7 @@ class WorkspacePreferenceCreateRequest @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val name: JsonField, + private val description: JsonField, private val hasCustomRouting: JsonField, private val routingOptions: JsonField>, private val additionalProperties: MutableMap, @@ -33,13 +34,16 @@ private constructor( @JsonCreator private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("has_custom_routing") @ExcludeMissing hasCustomRouting: JsonField = JsonMissing.of(), @JsonProperty("routing_options") @ExcludeMissing routingOptions: JsonField> = JsonMissing.of(), - ) : this(name, hasCustomRouting, routingOptions, mutableMapOf()) + ) : this(name, description, hasCustomRouting, routingOptions, mutableMapOf()) /** * Human-readable name for the workspace preference. @@ -49,6 +53,14 @@ private constructor( */ fun name(): String = name.getRequired("name") + /** + * Optional description shown under the section on the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * Whether the workspace preference defines custom routing for its topics. * @@ -73,6 +85,13 @@ private constructor( */ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [hasCustomRouting]. * @@ -122,6 +141,7 @@ private constructor( class Builder internal constructor() { private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() private var hasCustomRouting: JsonField = JsonMissing.of() private var routingOptions: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -130,6 +150,7 @@ private constructor( internal fun from(workspacePreferenceCreateRequest: WorkspacePreferenceCreateRequest) = apply { name = workspacePreferenceCreateRequest.name + description = workspacePreferenceCreateRequest.description hasCustomRouting = workspacePreferenceCreateRequest.hasCustomRouting routingOptions = workspacePreferenceCreateRequest.routingOptions.map { it.toMutableList() } @@ -148,6 +169,21 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** Optional description shown under the section on the hosted preferences page. */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** Whether the workspace preference defines custom routing for its topics. */ fun hasCustomRouting(hasCustomRouting: Boolean?) = hasCustomRouting(JsonField.ofNullable(hasCustomRouting)) @@ -240,6 +276,7 @@ private constructor( fun build(): WorkspacePreferenceCreateRequest = WorkspacePreferenceCreateRequest( checkRequired("name", name), + description, hasCustomRouting, (routingOptions ?: JsonMissing.of()).map { it.toImmutable() }, additionalProperties.toMutableMap(), @@ -262,6 +299,7 @@ private constructor( } name() + description() hasCustomRouting() routingOptions().ifPresent { it.forEach { it.validate() } } validated = true @@ -283,6 +321,7 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (name.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (hasCustomRouting.asKnown().isPresent) 1 else 0) + (routingOptions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) @@ -293,17 +332,18 @@ private constructor( return other is WorkspacePreferenceCreateRequest && name == other.name && + description == other.description && hasCustomRouting == other.hasCustomRouting && routingOptions == other.routingOptions && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(name, hasCustomRouting, routingOptions, additionalProperties) + Objects.hash(name, description, hasCustomRouting, routingOptions, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceCreateRequest{name=$name, hasCustomRouting=$hasCustomRouting, routingOptions=$routingOptions, additionalProperties=$additionalProperties}" + "WorkspacePreferenceCreateRequest{name=$name, description=$description, hasCustomRouting=$hasCustomRouting, routingOptions=$routingOptions, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponse.kt index 517d1718..2a57b8c8 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponse.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponse.kt @@ -31,6 +31,7 @@ private constructor( private val routingOptions: JsonField>, private val topics: JsonField>, private val creator: JsonField, + private val description: JsonField, private val updated: JsonField, private val updater: JsonField, private val additionalProperties: MutableMap, @@ -51,6 +52,9 @@ private constructor( @ExcludeMissing topics: JsonField> = JsonMissing.of(), @JsonProperty("creator") @ExcludeMissing creator: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), @JsonProperty("updater") @ExcludeMissing updater: JsonField = JsonMissing.of(), ) : this( @@ -61,6 +65,7 @@ private constructor( routingOptions, topics, creator, + description, updated, updater, mutableMapOf(), @@ -123,6 +128,14 @@ private constructor( */ fun creator(): Optional = creator.getOptional("creator") + /** + * Optional description shown under the section on the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * ISO-8601 timestamp of the last update. * @@ -195,6 +208,13 @@ private constructor( */ @JsonProperty("creator") @ExcludeMissing fun _creator(): JsonField = creator + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [updated]. * @@ -250,6 +270,7 @@ private constructor( private var routingOptions: JsonField>? = null private var topics: JsonField>? = null private var creator: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var updated: JsonField = JsonMissing.of() private var updater: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -264,6 +285,7 @@ private constructor( workspacePreferenceGetResponse.routingOptions.map { it.toMutableList() } topics = workspacePreferenceGetResponse.topics.map { it.toMutableList() } creator = workspacePreferenceGetResponse.creator + description = workspacePreferenceGetResponse.description updated = workspacePreferenceGetResponse.updated updater = workspacePreferenceGetResponse.updater additionalProperties = @@ -385,6 +407,21 @@ private constructor( */ fun creator(creator: JsonField) = apply { this.creator = creator } + /** Optional description shown under the section on the hosted preferences page. */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** ISO-8601 timestamp of the last update. */ fun updated(updated: String?) = updated(JsonField.ofNullable(updated)) @@ -458,6 +495,7 @@ private constructor( checkRequired("routingOptions", routingOptions).map { it.toImmutable() }, checkRequired("topics", topics).map { it.toImmutable() }, creator, + description, updated, updater, additionalProperties.toMutableMap(), @@ -486,6 +524,7 @@ private constructor( routingOptions().forEach { it.validate() } topics().forEach { it.validate() } creator() + description() updated() updater() validated = true @@ -513,6 +552,7 @@ private constructor( (routingOptions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (topics.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (creator.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (updated.asKnown().isPresent) 1 else 0) + (if (updater.asKnown().isPresent) 1 else 0) @@ -529,6 +569,7 @@ private constructor( routingOptions == other.routingOptions && topics == other.topics && creator == other.creator && + description == other.description && updated == other.updated && updater == other.updater && additionalProperties == other.additionalProperties @@ -543,6 +584,7 @@ private constructor( routingOptions, topics, creator, + description, updated, updater, additionalProperties, @@ -552,5 +594,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceGetResponse{id=$id, created=$created, hasCustomRouting=$hasCustomRouting, name=$name, routingOptions=$routingOptions, topics=$topics, creator=$creator, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" + "WorkspacePreferenceGetResponse{id=$id, created=$created, hasCustomRouting=$hasCustomRouting, name=$name, routingOptions=$routingOptions, topics=$topics, creator=$creator, description=$description, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParams.kt index 72b744b0..813d4925 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParams.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParams.kt @@ -6,9 +6,10 @@ import com.courier.core.JsonValue import com.courier.core.Params import com.courier.core.http.Headers import com.courier.core.http.QueryParams -import com.courier.core.toImmutable +import com.courier.core.immutableEmptyMap import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Publish the workspace's preferences page. Takes a snapshot of every workspace preference with its @@ -17,13 +18,21 @@ import java.util.Optional */ class WorkspacePreferencePublishParams private constructor( + private val publishPreferencesRequest: PublishPreferencesRequest?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, - private val additionalBodyProperties: Map, ) : Params { - /** Additional body properties to send with the request. */ - fun _additionalBodyProperties(): Map = additionalBodyProperties + /** + * Optional page metadata to apply when publishing the workspace's preferences page. All fields + * are optional; omitted fields fall back to the page defaults (and the workspace default + * brand). + */ + fun publishPreferencesRequest(): Optional = + Optional.ofNullable(publishPreferencesRequest) + + fun _additionalBodyProperties(): Map = + publishPreferencesRequest?._additionalProperties() ?: immutableEmptyMap() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -47,20 +56,38 @@ private constructor( /** A builder for [WorkspacePreferencePublishParams]. */ class Builder internal constructor() { + private var publishPreferencesRequest: PublishPreferencesRequest? = null private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(workspacePreferencePublishParams: WorkspacePreferencePublishParams) = apply { + publishPreferencesRequest = + workspacePreferencePublishParams.publishPreferencesRequest additionalHeaders = workspacePreferencePublishParams.additionalHeaders.toBuilder() additionalQueryParams = workspacePreferencePublishParams.additionalQueryParams.toBuilder() - additionalBodyProperties = - workspacePreferencePublishParams.additionalBodyProperties.toMutableMap() } + /** + * Optional page metadata to apply when publishing the workspace's preferences page. All + * fields are optional; omitted fields fall back to the page defaults (and the workspace + * default brand). + */ + fun publishPreferencesRequest(publishPreferencesRequest: PublishPreferencesRequest?) = + apply { + this.publishPreferencesRequest = publishPreferencesRequest + } + + /** + * Alias for calling [Builder.publishPreferencesRequest] with + * `publishPreferencesRequest.orElse(null)`. + */ + fun publishPreferencesRequest( + publishPreferencesRequest: Optional + ) = publishPreferencesRequest(publishPreferencesRequest.getOrNull()) + fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() putAllAdditionalHeaders(additionalHeaders) @@ -159,28 +186,6 @@ private constructor( additionalQueryParams.removeAll(keys) } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - putAllAdditionalBodyProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { - additionalBodyProperties.remove(key) - } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalBodyProperty) - } - /** * Returns an immutable instance of [WorkspacePreferencePublishParams]. * @@ -188,14 +193,14 @@ private constructor( */ fun build(): WorkspacePreferencePublishParams = WorkspacePreferencePublishParams( + publishPreferencesRequest, additionalHeaders.build(), additionalQueryParams.build(), - additionalBodyProperties.toImmutable(), ) } - fun _body(): Optional> = - Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + fun _body(): Optional = + Optional.ofNullable(publishPreferencesRequest) override fun _headers(): Headers = additionalHeaders @@ -207,14 +212,14 @@ private constructor( } return other is WorkspacePreferencePublishParams && + publishPreferencesRequest == other.publishPreferencesRequest && additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams && - additionalBodyProperties == other.additionalBodyProperties + additionalQueryParams == other.additionalQueryParams } override fun hashCode(): Int = - Objects.hash(additionalHeaders, additionalQueryParams, additionalBodyProperties) + Objects.hash(publishPreferencesRequest, additionalHeaders, additionalQueryParams) override fun toString() = - "WorkspacePreferencePublishParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" + "WorkspacePreferencePublishParams{publishPreferencesRequest=$publishPreferencesRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequest.kt index 4f523625..d55d1227 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequest.kt @@ -28,6 +28,7 @@ class WorkspacePreferenceReplaceRequest @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val name: JsonField, + private val description: JsonField, private val hasCustomRouting: JsonField, private val routingOptions: JsonField>, private val additionalProperties: MutableMap, @@ -36,13 +37,16 @@ private constructor( @JsonCreator private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("has_custom_routing") @ExcludeMissing hasCustomRouting: JsonField = JsonMissing.of(), @JsonProperty("routing_options") @ExcludeMissing routingOptions: JsonField> = JsonMissing.of(), - ) : this(name, hasCustomRouting, routingOptions, mutableMapOf()) + ) : this(name, description, hasCustomRouting, routingOptions, mutableMapOf()) /** * Human-readable name for the workspace preference. @@ -52,6 +56,14 @@ private constructor( */ fun name(): String = name.getRequired("name") + /** + * Optional description shown under the section on the hosted preferences page. Omit to clear. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * Whether the workspace preference defines custom routing for its topics. * @@ -76,6 +88,13 @@ private constructor( */ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [hasCustomRouting]. * @@ -125,6 +144,7 @@ private constructor( class Builder internal constructor() { private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() private var hasCustomRouting: JsonField = JsonMissing.of() private var routingOptions: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -133,6 +153,7 @@ private constructor( internal fun from(workspacePreferenceReplaceRequest: WorkspacePreferenceReplaceRequest) = apply { name = workspacePreferenceReplaceRequest.name + description = workspacePreferenceReplaceRequest.description hasCustomRouting = workspacePreferenceReplaceRequest.hasCustomRouting routingOptions = workspacePreferenceReplaceRequest.routingOptions.map { it.toMutableList() } @@ -151,6 +172,24 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** + * Optional description shown under the section on the hosted preferences page. Omit to + * clear. + */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** Whether the workspace preference defines custom routing for its topics. */ fun hasCustomRouting(hasCustomRouting: Boolean?) = hasCustomRouting(JsonField.ofNullable(hasCustomRouting)) @@ -243,6 +282,7 @@ private constructor( fun build(): WorkspacePreferenceReplaceRequest = WorkspacePreferenceReplaceRequest( checkRequired("name", name), + description, hasCustomRouting, (routingOptions ?: JsonMissing.of()).map { it.toImmutable() }, additionalProperties.toMutableMap(), @@ -265,6 +305,7 @@ private constructor( } name() + description() hasCustomRouting() routingOptions().ifPresent { it.forEach { it.validate() } } validated = true @@ -286,6 +327,7 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (name.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (hasCustomRouting.asKnown().isPresent) 1 else 0) + (routingOptions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) @@ -296,17 +338,18 @@ private constructor( return other is WorkspacePreferenceReplaceRequest && name == other.name && + description == other.description && hasCustomRouting == other.hasCustomRouting && routingOptions == other.routingOptions && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(name, hasCustomRouting, routingOptions, additionalProperties) + Objects.hash(name, description, hasCustomRouting, routingOptions, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceReplaceRequest{name=$name, hasCustomRouting=$hasCustomRouting, routingOptions=$routingOptions, additionalProperties=$additionalProperties}" + "WorkspacePreferenceReplaceRequest{name=$name, description=$description, hasCustomRouting=$hasCustomRouting, routingOptions=$routingOptions, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequest.kt index 4a4d2f60..bdabd905 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequest.kt @@ -28,6 +28,7 @@ private constructor( private val defaultStatus: JsonField, private val name: JsonField, private val allowedPreferences: JsonField>, + private val description: JsonField, private val includeUnsubscribeHeader: JsonField, private val routingOptions: JsonField>, private val topicData: JsonField, @@ -43,6 +44,9 @@ private constructor( @JsonProperty("allowed_preferences") @ExcludeMissing allowedPreferences: JsonField> = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("include_unsubscribe_header") @ExcludeMissing includeUnsubscribeHeader: JsonField = JsonMissing.of(), @@ -56,6 +60,7 @@ private constructor( defaultStatus, name, allowedPreferences, + description, includeUnsubscribeHeader, routingOptions, topicData, @@ -87,6 +92,14 @@ private constructor( fun allowedPreferences(): Optional> = allowedPreferences.getOptional("allowed_preferences") + /** + * Optional description shown under the topic on the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * Whether to include a list-unsubscribe header on emails for this topic. * @@ -139,6 +152,13 @@ private constructor( @ExcludeMissing fun _allowedPreferences(): JsonField> = allowedPreferences + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [includeUnsubscribeHeader]. * @@ -198,6 +218,7 @@ private constructor( private var defaultStatus: JsonField? = null private var name: JsonField? = null private var allowedPreferences: JsonField>? = null + private var description: JsonField = JsonMissing.of() private var includeUnsubscribeHeader: JsonField = JsonMissing.of() private var routingOptions: JsonField>? = null private var topicData: JsonField = JsonMissing.of() @@ -211,6 +232,7 @@ private constructor( name = workspacePreferenceTopicCreateRequest.name allowedPreferences = workspacePreferenceTopicCreateRequest.allowedPreferences.map { it.toMutableList() } + description = workspacePreferenceTopicCreateRequest.description includeUnsubscribeHeader = workspacePreferenceTopicCreateRequest.includeUnsubscribeHeader routingOptions = @@ -281,6 +303,21 @@ private constructor( } } + /** Optional description shown under the topic on the hosted preferences page. */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** Whether to include a list-unsubscribe header on emails for this topic. */ fun includeUnsubscribeHeader(includeUnsubscribeHeader: Boolean?) = includeUnsubscribeHeader(JsonField.ofNullable(includeUnsubscribeHeader)) @@ -394,6 +431,7 @@ private constructor( checkRequired("defaultStatus", defaultStatus), checkRequired("name", name), (allowedPreferences ?: JsonMissing.of()).map { it.toImmutable() }, + description, includeUnsubscribeHeader, (routingOptions ?: JsonMissing.of()).map { it.toImmutable() }, topicData, @@ -419,6 +457,7 @@ private constructor( defaultStatus().validate() name() allowedPreferences().ifPresent { it.forEach { it.validate() } } + description() includeUnsubscribeHeader() routingOptions().ifPresent { it.forEach { it.validate() } } topicData().ifPresent { it.validate() } @@ -443,6 +482,7 @@ private constructor( (defaultStatus.asKnown().getOrNull()?.validity() ?: 0) + (if (name.asKnown().isPresent) 1 else 0) + (allowedPreferences.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (includeUnsubscribeHeader.asKnown().isPresent) 1 else 0) + (routingOptions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (topicData.asKnown().getOrNull()?.validity() ?: 0) @@ -849,6 +889,7 @@ private constructor( defaultStatus == other.defaultStatus && name == other.name && allowedPreferences == other.allowedPreferences && + description == other.description && includeUnsubscribeHeader == other.includeUnsubscribeHeader && routingOptions == other.routingOptions && topicData == other.topicData && @@ -860,6 +901,7 @@ private constructor( defaultStatus, name, allowedPreferences, + description, includeUnsubscribeHeader, routingOptions, topicData, @@ -870,5 +912,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceTopicCreateRequest{defaultStatus=$defaultStatus, name=$name, allowedPreferences=$allowedPreferences, includeUnsubscribeHeader=$includeUnsubscribeHeader, routingOptions=$routingOptions, topicData=$topicData, additionalProperties=$additionalProperties}" + "WorkspacePreferenceTopicCreateRequest{defaultStatus=$defaultStatus, name=$name, allowedPreferences=$allowedPreferences, description=$description, includeUnsubscribeHeader=$includeUnsubscribeHeader, routingOptions=$routingOptions, topicData=$topicData, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponse.kt index f512e0be..2d03b2dc 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponse.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponse.kt @@ -35,6 +35,7 @@ private constructor( private val topicData: JsonField, private val updated: JsonField, private val creator: JsonField, + private val description: JsonField, private val updater: JsonField, private val additionalProperties: MutableMap, ) { @@ -61,6 +62,9 @@ private constructor( topicData: JsonField = JsonMissing.of(), @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), @JsonProperty("creator") @ExcludeMissing creator: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("updater") @ExcludeMissing updater: JsonField = JsonMissing.of(), ) : this( id, @@ -73,6 +77,7 @@ private constructor( topicData, updated, creator, + description, updater, mutableMapOf(), ) @@ -160,6 +165,14 @@ private constructor( */ fun creator(): Optional = creator.getOptional("creator") + /** + * Optional description shown under the topic on the hosted preferences page. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * Id of the last updater. * @@ -248,6 +261,13 @@ private constructor( */ @JsonProperty("creator") @ExcludeMissing fun _creator(): JsonField = creator + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [updater]. * @@ -302,6 +322,7 @@ private constructor( private var topicData: JsonField? = null private var updated: JsonField? = null private var creator: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var updater: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -321,6 +342,7 @@ private constructor( topicData = workspacePreferenceTopicGetResponse.topicData updated = workspacePreferenceTopicGetResponse.updated creator = workspacePreferenceTopicGetResponse.creator + description = workspacePreferenceTopicGetResponse.description updater = workspacePreferenceTopicGetResponse.updater additionalProperties = workspacePreferenceTopicGetResponse.additionalProperties.toMutableMap() @@ -479,6 +501,21 @@ private constructor( */ fun creator(creator: JsonField) = apply { this.creator = creator } + /** Optional description shown under the topic on the hosted preferences page. */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** Id of the last updater. */ fun updater(updater: String?) = updater(JsonField.ofNullable(updater)) @@ -544,6 +581,7 @@ private constructor( checkRequired("topicData", topicData), checkRequired("updated", updated), creator, + description, updater, additionalProperties.toMutableMap(), ) @@ -574,6 +612,7 @@ private constructor( topicData().validate() updated() creator() + description() updater() validated = true } @@ -603,6 +642,7 @@ private constructor( (topicData.asKnown().getOrNull()?.validity() ?: 0) + (if (updated.asKnown().isPresent) 1 else 0) + (if (creator.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (updater.asKnown().isPresent) 1 else 0) /** A preference control a recipient may customize for a topic. */ @@ -1014,6 +1054,7 @@ private constructor( topicData == other.topicData && updated == other.updated && creator == other.creator && + description == other.description && updater == other.updater && additionalProperties == other.additionalProperties } @@ -1030,6 +1071,7 @@ private constructor( topicData, updated, creator, + description, updater, additionalProperties, ) @@ -1038,5 +1080,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceTopicGetResponse{id=$id, allowedPreferences=$allowedPreferences, created=$created, defaultStatus=$defaultStatus, includeUnsubscribeHeader=$includeUnsubscribeHeader, name=$name, routingOptions=$routingOptions, topicData=$topicData, updated=$updated, creator=$creator, updater=$updater, additionalProperties=$additionalProperties}" + "WorkspacePreferenceTopicGetResponse{id=$id, allowedPreferences=$allowedPreferences, created=$created, defaultStatus=$defaultStatus, includeUnsubscribeHeader=$includeUnsubscribeHeader, name=$name, routingOptions=$routingOptions, topicData=$topicData, updated=$updated, creator=$creator, description=$description, updater=$updater, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequest.kt index cc2c78d9..8e667016 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequest.kt @@ -31,6 +31,7 @@ private constructor( private val defaultStatus: JsonField, private val name: JsonField, private val allowedPreferences: JsonField>, + private val description: JsonField, private val includeUnsubscribeHeader: JsonField, private val routingOptions: JsonField>, private val topicData: JsonField, @@ -46,6 +47,9 @@ private constructor( @JsonProperty("allowed_preferences") @ExcludeMissing allowedPreferences: JsonField> = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), @JsonProperty("include_unsubscribe_header") @ExcludeMissing includeUnsubscribeHeader: JsonField = JsonMissing.of(), @@ -59,6 +63,7 @@ private constructor( defaultStatus, name, allowedPreferences, + description, includeUnsubscribeHeader, routingOptions, topicData, @@ -90,6 +95,14 @@ private constructor( fun allowedPreferences(): Optional> = allowedPreferences.getOptional("allowed_preferences") + /** + * Optional description shown under the topic on the hosted preferences page. Omit to clear. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + /** * Whether to include a list-unsubscribe header on emails for this topic. * @@ -142,6 +155,13 @@ private constructor( @ExcludeMissing fun _allowedPreferences(): JsonField> = allowedPreferences + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + /** * Returns the raw JSON value of [includeUnsubscribeHeader]. * @@ -201,6 +221,7 @@ private constructor( private var defaultStatus: JsonField? = null private var name: JsonField? = null private var allowedPreferences: JsonField>? = null + private var description: JsonField = JsonMissing.of() private var includeUnsubscribeHeader: JsonField = JsonMissing.of() private var routingOptions: JsonField>? = null private var topicData: JsonField = JsonMissing.of() @@ -214,6 +235,7 @@ private constructor( name = workspacePreferenceTopicReplaceRequest.name allowedPreferences = workspacePreferenceTopicReplaceRequest.allowedPreferences.map { it.toMutableList() } + description = workspacePreferenceTopicReplaceRequest.description includeUnsubscribeHeader = workspacePreferenceTopicReplaceRequest.includeUnsubscribeHeader routingOptions = @@ -281,6 +303,23 @@ private constructor( } } + /** + * Optional description shown under the topic on the hosted preferences page. Omit to clear. + */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + /** Whether to include a list-unsubscribe header on emails for this topic. */ fun includeUnsubscribeHeader(includeUnsubscribeHeader: Boolean?) = includeUnsubscribeHeader(JsonField.ofNullable(includeUnsubscribeHeader)) @@ -394,6 +433,7 @@ private constructor( checkRequired("defaultStatus", defaultStatus), checkRequired("name", name), (allowedPreferences ?: JsonMissing.of()).map { it.toImmutable() }, + description, includeUnsubscribeHeader, (routingOptions ?: JsonMissing.of()).map { it.toImmutable() }, topicData, @@ -419,6 +459,7 @@ private constructor( defaultStatus().validate() name() allowedPreferences().ifPresent { it.forEach { it.validate() } } + description() includeUnsubscribeHeader() routingOptions().ifPresent { it.forEach { it.validate() } } topicData().ifPresent { it.validate() } @@ -443,6 +484,7 @@ private constructor( (defaultStatus.asKnown().getOrNull()?.validity() ?: 0) + (if (name.asKnown().isPresent) 1 else 0) + (allowedPreferences.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (includeUnsubscribeHeader.asKnown().isPresent) 1 else 0) + (routingOptions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (topicData.asKnown().getOrNull()?.validity() ?: 0) @@ -849,6 +891,7 @@ private constructor( defaultStatus == other.defaultStatus && name == other.name && allowedPreferences == other.allowedPreferences && + description == other.description && includeUnsubscribeHeader == other.includeUnsubscribeHeader && routingOptions == other.routingOptions && topicData == other.topicData && @@ -860,6 +903,7 @@ private constructor( defaultStatus, name, allowedPreferences, + description, includeUnsubscribeHeader, routingOptions, topicData, @@ -870,5 +914,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "WorkspacePreferenceTopicReplaceRequest{defaultStatus=$defaultStatus, name=$name, allowedPreferences=$allowedPreferences, includeUnsubscribeHeader=$includeUnsubscribeHeader, routingOptions=$routingOptions, topicData=$topicData, additionalProperties=$additionalProperties}" + "WorkspacePreferenceTopicReplaceRequest{defaultStatus=$defaultStatus, name=$name, allowedPreferences=$allowedPreferences, description=$description, includeUnsubscribeHeader=$includeUnsubscribeHeader, routingOptions=$routingOptions, topicData=$topicData, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsync.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsync.kt index 050aacba..e47246dc 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsync.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsync.kt @@ -6,6 +6,7 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.workspacepreferences.PublishPreferencesRequest import com.courier.models.workspacepreferences.PublishPreferencesResponse import com.courier.models.workspacepreferences.WorkspacePreferenceArchiveParams import com.courier.models.workspacepreferences.WorkspacePreferenceCreateParams @@ -181,6 +182,24 @@ interface WorkspacePreferenceServiceAsync { params: WorkspacePreferencePublishParams = WorkspacePreferencePublishParams.none() ): CompletableFuture = publish(params, RequestOptions.none()) + /** @see publish */ + fun publish( + publishPreferencesRequest: PublishPreferencesRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + publish( + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest(publishPreferencesRequest) + .build(), + requestOptions, + ) + + /** @see publish */ + fun publish( + publishPreferencesRequest: PublishPreferencesRequest + ): CompletableFuture = + publish(publishPreferencesRequest, RequestOptions.none()) + /** @see publish */ fun publish(requestOptions: RequestOptions): CompletableFuture = publish(WorkspacePreferencePublishParams.none(), requestOptions) @@ -389,6 +408,24 @@ interface WorkspacePreferenceServiceAsync { ): CompletableFuture> = publish(params, RequestOptions.none()) + /** @see publish */ + fun publish( + publishPreferencesRequest: PublishPreferencesRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + publish( + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest(publishPreferencesRequest) + .build(), + requestOptions, + ) + + /** @see publish */ + fun publish( + publishPreferencesRequest: PublishPreferencesRequest + ): CompletableFuture> = + publish(publishPreferencesRequest, RequestOptions.none()) + /** @see publish */ fun publish( requestOptions: RequestOptions diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsync.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsync.kt index 5fea9e13..5b129471 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsync.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsync.kt @@ -6,6 +6,10 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkReplaceResponse +import com.courier.models.users.preferences.PreferenceBulkUpdateParams +import com.courier.models.users.preferences.PreferenceBulkUpdateResponse import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveResponse @@ -66,6 +70,89 @@ interface PreferenceServiceAsync { ): CompletableFuture = retrieve(userId, PreferenceRetrieveParams.none(), requestOptions) + /** + * Replace a user's complete set of preference overrides in a single request. The topics in the + * request body become the recipient's entire set of overrides: listed topics are created or + * updated, and every existing override that is not included in the body is reset to its topic + * default. Submitting an empty `topics` array is a valid clear-all that resets every existing + * override. + * + * This operation is validation-atomic (all-or-nothing): structural validation fails fast with a + * single `400`, and if any topic is semantically invalid (an unknown topic, a `REQUIRED` topic + * that cannot be opted out, or a custom routing request that is not available on the + * workspace's plan) the request returns a single `400` aggregating every failure in `errors` + * and writes nothing. On success it returns `200` with `items` (the complete resulting override + * set) and `deleted` (the ids of the overrides that were reset to default). + * + * Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is returned in + * Courier's canonical topic id form, regardless of the form supplied in the request. + */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + ): CompletableFuture = + bulkReplace(userId, params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + bulkReplace(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkReplace */ + fun bulkReplace( + params: PreferenceBulkReplaceParams + ): CompletableFuture = bulkReplace(params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Additively create or update a user's preferences for one or more subscription topics in a + * single request. Only the topics included in the request body are created or updated; any + * existing overrides for topics not listed are left untouched. + * + * Structural validation of the request body fails fast with a single `400`. Beyond that, each + * topic is processed independently (partial-success, not all-or-nothing): valid topics are + * written and returned in `items`, while topics that cannot be applied are collected in + * `errors` with a per-topic `reason` (for example an unknown topic, a `REQUIRED` topic that + * cannot be opted out, a custom routing request that is not available on the workspace's plan, + * or a write failure). The request therefore returns `200` with both lists whenever the body is + * structurally valid. + * + * Every `topic_id` in the response — in both `items` and `errors` — is returned in Courier's + * canonical topic id form, regardless of the form supplied in the request. + */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + ): CompletableFuture = + bulkUpdate(userId, params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + bulkUpdate(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkUpdate */ + fun bulkUpdate( + params: PreferenceBulkUpdateParams + ): CompletableFuture = bulkUpdate(params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + /** * Remove a user's preferences for a specific subscription topic, resetting the topic to its * effective default. This operation is idempotent: deleting a preference that does not exist @@ -206,6 +293,66 @@ interface PreferenceServiceAsync { ): CompletableFuture> = retrieve(userId, PreferenceRetrieveParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `put /users/{user_id}/preferences`, but is otherwise the + * same as [PreferenceServiceAsync.bulkReplace]. + */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + ): CompletableFuture> = + bulkReplace(userId, params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + bulkReplace(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkReplace */ + fun bulkReplace( + params: PreferenceBulkReplaceParams + ): CompletableFuture> = + bulkReplace(params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /users/{user_id}/preferences`, but is otherwise the + * same as [PreferenceServiceAsync.bulkUpdate]. + */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + ): CompletableFuture> = + bulkUpdate(userId, params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + bulkUpdate(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkUpdate */ + fun bulkUpdate( + params: PreferenceBulkUpdateParams + ): CompletableFuture> = + bulkUpdate(params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + /** * Returns a raw HTTP response for `delete /users/{user_id}/preferences/{topic_id}`, but is * otherwise the same as [PreferenceServiceAsync.deleteTopic]. diff --git a/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsyncImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsyncImpl.kt index 95835d6e..733cacbc 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsyncImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/async/users/PreferenceServiceAsyncImpl.kt @@ -17,6 +17,10 @@ import com.courier.core.http.HttpResponseFor import com.courier.core.http.json import com.courier.core.http.parseable import com.courier.core.prepareAsync +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkReplaceResponse +import com.courier.models.users.preferences.PreferenceBulkUpdateParams +import com.courier.models.users.preferences.PreferenceBulkUpdateResponse import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveResponse @@ -47,6 +51,20 @@ class PreferenceServiceAsyncImpl internal constructor(private val clientOptions: // get /users/{user_id}/preferences withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + override fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /users/{user_id}/preferences + withRawResponse().bulkReplace(params, requestOptions).thenApply { it.parse() } + + override fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /users/{user_id}/preferences + withRawResponse().bulkUpdate(params, requestOptions).thenApply { it.parse() } + override fun deleteTopic( params: PreferenceDeleteTopicParams, requestOptions: RequestOptions, @@ -114,6 +132,74 @@ class PreferenceServiceAsyncImpl internal constructor(private val clientOptions: } } + private val bulkReplaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("userId", params.userId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("users", params._pathParam(0), "preferences") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { bulkReplaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val bulkUpdateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("userId", params.userId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("users", params._pathParam(0), "preferences") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { bulkUpdateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val deleteTopicHandler: Handler = emptyHandler() override fun deleteTopic( diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/WorkspacePreferenceService.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/WorkspacePreferenceService.kt index 662a04b1..49915266 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/WorkspacePreferenceService.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/WorkspacePreferenceService.kt @@ -6,6 +6,7 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.workspacepreferences.PublishPreferencesRequest import com.courier.models.workspacepreferences.PublishPreferencesResponse import com.courier.models.workspacepreferences.WorkspacePreferenceArchiveParams import com.courier.models.workspacepreferences.WorkspacePreferenceCreateParams @@ -173,6 +174,22 @@ interface WorkspacePreferenceService { params: WorkspacePreferencePublishParams = WorkspacePreferencePublishParams.none() ): PublishPreferencesResponse = publish(params, RequestOptions.none()) + /** @see publish */ + fun publish( + publishPreferencesRequest: PublishPreferencesRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): PublishPreferencesResponse = + publish( + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest(publishPreferencesRequest) + .build(), + requestOptions, + ) + + /** @see publish */ + fun publish(publishPreferencesRequest: PublishPreferencesRequest): PublishPreferencesResponse = + publish(publishPreferencesRequest, RequestOptions.none()) + /** @see publish */ fun publish(requestOptions: RequestOptions): PublishPreferencesResponse = publish(WorkspacePreferencePublishParams.none(), requestOptions) @@ -390,6 +407,26 @@ interface WorkspacePreferenceService { params: WorkspacePreferencePublishParams = WorkspacePreferencePublishParams.none() ): HttpResponseFor = publish(params, RequestOptions.none()) + /** @see publish */ + @MustBeClosed + fun publish( + publishPreferencesRequest: PublishPreferencesRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + publish( + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest(publishPreferencesRequest) + .build(), + requestOptions, + ) + + /** @see publish */ + @MustBeClosed + fun publish( + publishPreferencesRequest: PublishPreferencesRequest + ): HttpResponseFor = + publish(publishPreferencesRequest, RequestOptions.none()) + /** @see publish */ @MustBeClosed fun publish(requestOptions: RequestOptions): HttpResponseFor = diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceService.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceService.kt index c0f45b07..79034d92 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceService.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceService.kt @@ -6,6 +6,10 @@ import com.courier.core.ClientOptions import com.courier.core.RequestOptions import com.courier.core.http.HttpResponse import com.courier.core.http.HttpResponseFor +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkReplaceResponse +import com.courier.models.users.preferences.PreferenceBulkUpdateParams +import com.courier.models.users.preferences.PreferenceBulkUpdateResponse import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveResponse @@ -62,6 +66,85 @@ interface PreferenceService { fun retrieve(userId: String, requestOptions: RequestOptions): PreferenceRetrieveResponse = retrieve(userId, PreferenceRetrieveParams.none(), requestOptions) + /** + * Replace a user's complete set of preference overrides in a single request. The topics in the + * request body become the recipient's entire set of overrides: listed topics are created or + * updated, and every existing override that is not included in the body is reset to its topic + * default. Submitting an empty `topics` array is a valid clear-all that resets every existing + * override. + * + * This operation is validation-atomic (all-or-nothing): structural validation fails fast with a + * single `400`, and if any topic is semantically invalid (an unknown topic, a `REQUIRED` topic + * that cannot be opted out, or a custom routing request that is not available on the + * workspace's plan) the request returns a single `400` aggregating every failure in `errors` + * and writes nothing. On success it returns `200` with `items` (the complete resulting override + * set) and `deleted` (the ids of the overrides that were reset to default). + * + * Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is returned in + * Courier's canonical topic id form, regardless of the form supplied in the request. + */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + ): PreferenceBulkReplaceResponse = bulkReplace(userId, params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PreferenceBulkReplaceResponse = + bulkReplace(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkReplace */ + fun bulkReplace(params: PreferenceBulkReplaceParams): PreferenceBulkReplaceResponse = + bulkReplace(params, RequestOptions.none()) + + /** @see bulkReplace */ + fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PreferenceBulkReplaceResponse + + /** + * Additively create or update a user's preferences for one or more subscription topics in a + * single request. Only the topics included in the request body are created or updated; any + * existing overrides for topics not listed are left untouched. + * + * Structural validation of the request body fails fast with a single `400`. Beyond that, each + * topic is processed independently (partial-success, not all-or-nothing): valid topics are + * written and returned in `items`, while topics that cannot be applied are collected in + * `errors` with a per-topic `reason` (for example an unknown topic, a `REQUIRED` topic that + * cannot be opted out, a custom routing request that is not available on the workspace's plan, + * or a write failure). The request therefore returns `200` with both lists whenever the body is + * structurally valid. + * + * Every `topic_id` in the response — in both `items` and `errors` — is returned in Courier's + * canonical topic id form, regardless of the form supplied in the request. + */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + ): PreferenceBulkUpdateResponse = bulkUpdate(userId, params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PreferenceBulkUpdateResponse = + bulkUpdate(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkUpdate */ + fun bulkUpdate(params: PreferenceBulkUpdateParams): PreferenceBulkUpdateResponse = + bulkUpdate(params, RequestOptions.none()) + + /** @see bulkUpdate */ + fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PreferenceBulkUpdateResponse + /** * Remove a user's preferences for a specific subscription topic, resetting the topic to its * effective default. This operation is idempotent: deleting a preference that does not exist @@ -195,6 +278,73 @@ interface PreferenceService { ): HttpResponseFor = retrieve(userId, PreferenceRetrieveParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `put /users/{user_id}/preferences`, but is otherwise the + * same as [PreferenceService.bulkReplace]. + */ + @MustBeClosed + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + ): HttpResponseFor = + bulkReplace(userId, params, RequestOptions.none()) + + /** @see bulkReplace */ + @MustBeClosed + fun bulkReplace( + userId: String, + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + bulkReplace(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkReplace */ + @MustBeClosed + fun bulkReplace( + params: PreferenceBulkReplaceParams + ): HttpResponseFor = + bulkReplace(params, RequestOptions.none()) + + /** @see bulkReplace */ + @MustBeClosed + fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /users/{user_id}/preferences`, but is otherwise the + * same as [PreferenceService.bulkUpdate]. + */ + @MustBeClosed + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + ): HttpResponseFor = + bulkUpdate(userId, params, RequestOptions.none()) + + /** @see bulkUpdate */ + @MustBeClosed + fun bulkUpdate( + userId: String, + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + bulkUpdate(params.toBuilder().userId(userId).build(), requestOptions) + + /** @see bulkUpdate */ + @MustBeClosed + fun bulkUpdate( + params: PreferenceBulkUpdateParams + ): HttpResponseFor = bulkUpdate(params, RequestOptions.none()) + + /** @see bulkUpdate */ + @MustBeClosed + fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + /** * Returns a raw HTTP response for `delete /users/{user_id}/preferences/{topic_id}`, but is * otherwise the same as [PreferenceService.deleteTopic]. diff --git a/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceServiceImpl.kt b/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceServiceImpl.kt index d072bb6c..862cd0ff 100644 --- a/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceServiceImpl.kt +++ b/courier-java-core/src/main/kotlin/com/courier/services/blocking/users/PreferenceServiceImpl.kt @@ -17,6 +17,10 @@ import com.courier.core.http.HttpResponseFor import com.courier.core.http.json import com.courier.core.http.parseable import com.courier.core.prepare +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkReplaceResponse +import com.courier.models.users.preferences.PreferenceBulkUpdateParams +import com.courier.models.users.preferences.PreferenceBulkUpdateResponse import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveResponse @@ -46,6 +50,20 @@ class PreferenceServiceImpl internal constructor(private val clientOptions: Clie // get /users/{user_id}/preferences withRawResponse().retrieve(params, requestOptions).parse() + override fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions, + ): PreferenceBulkReplaceResponse = + // put /users/{user_id}/preferences + withRawResponse().bulkReplace(params, requestOptions).parse() + + override fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions, + ): PreferenceBulkUpdateResponse = + // post /users/{user_id}/preferences + withRawResponse().bulkUpdate(params, requestOptions).parse() + override fun deleteTopic(params: PreferenceDeleteTopicParams, requestOptions: RequestOptions) { // delete /users/{user_id}/preferences/{topic_id} withRawResponse().deleteTopic(params, requestOptions) @@ -108,6 +126,68 @@ class PreferenceServiceImpl internal constructor(private val clientOptions: Clie } } + private val bulkReplaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun bulkReplace( + params: PreferenceBulkReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("userId", params.userId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("users", params._pathParam(0), "preferences") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { bulkReplaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val bulkUpdateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun bulkUpdate( + params: PreferenceBulkUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("userId", params.userId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("users", params._pathParam(0), "preferences") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { bulkUpdateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val deleteTopicHandler: Handler = emptyHandler() override fun deleteTopic( diff --git a/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/BulkPreferenceTopicTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/BulkPreferenceTopicTest.kt new file mode 100644 index 00000000..f5afa337 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/BulkPreferenceTopicTest.kt @@ -0,0 +1,49 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.jsonMapper +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BulkPreferenceTopicTest { + + @Test + fun create() { + val bulkPreferenceTopic = + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + + assertThat(bulkPreferenceTopic.customRouting()) + .containsExactly(ChannelClassification.DIRECT_MESSAGE) + assertThat(bulkPreferenceTopic.hasCustomRouting()).isEqualTo(true) + assertThat(bulkPreferenceTopic.status()).isEqualTo(BulkPreferenceTopic.Status.OPTED_IN) + assertThat(bulkPreferenceTopic.topicId()).isEqualTo("topic_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val bulkPreferenceTopic = + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + + val roundtrippedBulkPreferenceTopic = + jsonMapper.readValue( + jsonMapper.writeValueAsString(bulkPreferenceTopic), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBulkPreferenceTopic).isEqualTo(bulkPreferenceTopic) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParamsTest.kt new file mode 100644 index 00000000..cff6bdef --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceParamsTest.kt @@ -0,0 +1,142 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.http.QueryParams +import com.courier.models.ChannelClassification +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PreferenceBulkReplaceParamsTest { + + @Test + fun create() { + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("user_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun queryParams() { + val params = + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo(QueryParams.builder().put("tenant_id", "tenant_id").build()) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } + + @Test + fun body() { + val params = + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .build() + + val body = params._body() + + assertThat(body.topics()) + .containsExactly( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .build() + + val body = params._body() + + assertThat(body.topics()) + .containsExactly( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponseTest.kt new file mode 100644 index 00000000..003566a3 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkReplaceResponseTest.kt @@ -0,0 +1,65 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.jsonMapper +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PreferenceBulkReplaceResponseTest { + + @Test + fun create() { + val preferenceBulkReplaceResponse = + PreferenceBulkReplaceResponse.builder() + .addDeleted("string") + .addItem( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + .build() + + assertThat(preferenceBulkReplaceResponse.deleted()).containsExactly("string") + assertThat(preferenceBulkReplaceResponse.items()) + .containsExactly( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val preferenceBulkReplaceResponse = + PreferenceBulkReplaceResponse.builder() + .addDeleted("string") + .addItem( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + .build() + + val roundtrippedPreferenceBulkReplaceResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(preferenceBulkReplaceResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPreferenceBulkReplaceResponse) + .isEqualTo(preferenceBulkReplaceResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParamsTest.kt new file mode 100644 index 00000000..c2a83f3f --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateParamsTest.kt @@ -0,0 +1,194 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.http.QueryParams +import com.courier.models.ChannelClassification +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PreferenceBulkUpdateParamsTest { + + @Test + fun create() { + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("user_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun queryParams() { + val params = + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build() + ) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo(QueryParams.builder().put("tenant_id", "tenant_id").build()) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .build() + ) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } + + @Test + fun body() { + val params = + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build() + ) + .build() + + val body = params._body() + + assertThat(body.topics()) + .containsExactly( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build(), + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build(), + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .build() + ) + .build() + + val body = params._body() + + assertThat(body.topics()) + .containsExactly( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .build(), + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .build(), + ) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponseTest.kt new file mode 100644 index 00000000..7a45486a --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/users/preferences/PreferenceBulkUpdateResponseTest.kt @@ -0,0 +1,80 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.users.preferences + +import com.courier.core.jsonMapper +import com.courier.models.ChannelClassification +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PreferenceBulkUpdateResponseTest { + + @Test + fun create() { + val preferenceBulkUpdateResponse = + PreferenceBulkUpdateResponse.builder() + .addError( + PreferenceBulkUpdateResponse.Error.builder() + .reason("reason") + .topicId("topic_id") + .build() + ) + .addItem( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + .build() + + assertThat(preferenceBulkUpdateResponse.errors()) + .containsExactly( + PreferenceBulkUpdateResponse.Error.builder() + .reason("reason") + .topicId("topic_id") + .build() + ) + assertThat(preferenceBulkUpdateResponse.items()) + .containsExactly( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val preferenceBulkUpdateResponse = + PreferenceBulkUpdateResponse.builder() + .addError( + PreferenceBulkUpdateResponse.Error.builder() + .reason("reason") + .topicId("topic_id") + .build() + ) + .addItem( + BulkPreferenceTopic.builder() + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .status(BulkPreferenceTopic.Status.OPTED_IN) + .topicId("topic_id") + .build() + ) + .build() + + val roundtrippedPreferenceBulkUpdateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(preferenceBulkUpdateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPreferenceBulkUpdateResponse).isEqualTo(preferenceBulkUpdateResponse) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequestTest.kt new file mode 100644 index 00000000..615faa74 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/PublishPreferencesRequestTest.kt @@ -0,0 +1,44 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.workspacepreferences + +import com.courier.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PublishPreferencesRequestTest { + + @Test + fun create() { + val publishPreferencesRequest = + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + + assertThat(publishPreferencesRequest.brandId()).contains("brand_id") + assertThat(publishPreferencesRequest.description()).contains("description") + assertThat(publishPreferencesRequest.heading()).contains("heading") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val publishPreferencesRequest = + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + + val roundtrippedPublishPreferencesRequest = + jsonMapper.readValue( + jsonMapper.writeValueAsString(publishPreferencesRequest), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPublishPreferencesRequest).isEqualTo(publishPreferencesRequest) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateParamsTest.kt index e4aadc3e..9d8776e8 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateParamsTest.kt @@ -14,6 +14,7 @@ internal class WorkspacePreferenceCreateParamsTest { .workspacePreferenceCreateRequest( WorkspacePreferenceCreateRequest.builder() .name("Account Notifications") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -28,6 +29,7 @@ internal class WorkspacePreferenceCreateParamsTest { .workspacePreferenceCreateRequest( WorkspacePreferenceCreateRequest.builder() .name("Account Notifications") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -40,6 +42,7 @@ internal class WorkspacePreferenceCreateParamsTest { .isEqualTo( WorkspacePreferenceCreateRequest.builder() .name("Account Notifications") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequestTest.kt index 2757bf81..b861824c 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceCreateRequestTest.kt @@ -16,11 +16,13 @@ internal class WorkspacePreferenceCreateRequestTest { val workspacePreferenceCreateRequest = WorkspacePreferenceCreateRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() assertThat(workspacePreferenceCreateRequest.name()).isEqualTo("name") + assertThat(workspacePreferenceCreateRequest.description()).contains("description") assertThat(workspacePreferenceCreateRequest.hasCustomRouting()).contains(true) assertThat(workspacePreferenceCreateRequest.routingOptions().getOrNull()) .containsExactly(ChannelClassification.DIRECT_MESSAGE) @@ -32,6 +34,7 @@ internal class WorkspacePreferenceCreateRequestTest { val workspacePreferenceCreateRequest = WorkspacePreferenceCreateRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponseTest.kt index bbfae02f..7b658ba5 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceGetResponseTest.kt @@ -38,10 +38,12 @@ internal class WorkspacePreferenceGetResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) .creator("creator") + .description("description") .updated("updated") .updater("updater") .build() @@ -71,10 +73,12 @@ internal class WorkspacePreferenceGetResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) assertThat(workspacePreferenceGetResponse.creator()).contains("creator") + assertThat(workspacePreferenceGetResponse.description()).contains("description") assertThat(workspacePreferenceGetResponse.updated()).contains("updated") assertThat(workspacePreferenceGetResponse.updater()).contains("updater") } @@ -107,10 +111,12 @@ internal class WorkspacePreferenceGetResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) .creator("creator") + .description("description") .updated("updated") .updater("updater") .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceListResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceListResponseTest.kt index 63aef38d..909d87c5 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceListResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceListResponseTest.kt @@ -42,10 +42,12 @@ internal class WorkspacePreferenceListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) .creator("creator") + .description("description") .updated("updated") .updater("updater") .build() @@ -80,10 +82,12 @@ internal class WorkspacePreferenceListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) .creator("creator") + .description("description") .updated("updated") .updater("updater") .build() @@ -122,10 +126,12 @@ internal class WorkspacePreferenceListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) .creator("creator") + .description("description") .updated("updated") .updater("updater") .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParamsTest.kt index f7ee239c..347c6cc9 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferencePublishParamsTest.kt @@ -2,12 +2,54 @@ package com.courier.models.workspacepreferences +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test internal class WorkspacePreferencePublishParamsTest { @Test fun create() { - WorkspacePreferencePublishParams.builder().build() + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest( + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + ) + .build() + } + + @Test + fun body() { + val params = + WorkspacePreferencePublishParams.builder() + .publishPreferencesRequest( + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + ) + .build() + + val body = params._body().getOrNull() + + assertThat(body) + .isEqualTo( + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = WorkspacePreferencePublishParams.builder().build() + + val body = params._body().getOrNull() } } diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceParamsTest.kt index e58f9f41..0503cbc9 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceParamsTest.kt @@ -15,6 +15,7 @@ internal class WorkspacePreferenceReplaceParamsTest { .workspacePreferenceReplaceRequest( WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -45,6 +46,7 @@ internal class WorkspacePreferenceReplaceParamsTest { .workspacePreferenceReplaceRequest( WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -57,6 +59,7 @@ internal class WorkspacePreferenceReplaceParamsTest { .isEqualTo( WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequestTest.kt index 070ac44e..d175ff09 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceReplaceRequestTest.kt @@ -16,11 +16,13 @@ internal class WorkspacePreferenceReplaceRequestTest { val workspacePreferenceReplaceRequest = WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() assertThat(workspacePreferenceReplaceRequest.name()).isEqualTo("name") + assertThat(workspacePreferenceReplaceRequest.description()).contains("description") assertThat(workspacePreferenceReplaceRequest.hasCustomRouting()).contains(true) assertThat(workspacePreferenceReplaceRequest.routingOptions().getOrNull()) .containsExactly(ChannelClassification.DIRECT_MESSAGE) @@ -32,6 +34,7 @@ internal class WorkspacePreferenceReplaceRequestTest { val workspacePreferenceReplaceRequest = WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequestTest.kt index f34bc579..3e39d6cc 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicCreateRequestTest.kt @@ -21,6 +21,7 @@ internal class WorkspacePreferenceTopicCreateRequestTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -35,6 +36,7 @@ internal class WorkspacePreferenceTopicCreateRequestTest { assertThat(workspacePreferenceTopicCreateRequest.name()).isEqualTo("name") assertThat(workspacePreferenceTopicCreateRequest.allowedPreferences().getOrNull()) .containsExactly(WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE) + assertThat(workspacePreferenceTopicCreateRequest.description()).contains("description") assertThat(workspacePreferenceTopicCreateRequest.includeUnsubscribeHeader()).contains(true) assertThat(workspacePreferenceTopicCreateRequest.routingOptions().getOrNull()) .containsExactly(ChannelClassification.DIRECT_MESSAGE) @@ -56,6 +58,7 @@ internal class WorkspacePreferenceTopicCreateRequestTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponseTest.kt index 0f759d8c..f39306de 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicGetResponseTest.kt @@ -29,6 +29,7 @@ internal class WorkspacePreferenceTopicGetResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() @@ -50,6 +51,7 @@ internal class WorkspacePreferenceTopicGetResponseTest { ) assertThat(workspacePreferenceTopicGetResponse.updated()).isEqualTo("updated") assertThat(workspacePreferenceTopicGetResponse.creator()).contains("creator") + assertThat(workspacePreferenceTopicGetResponse.description()).contains("description") assertThat(workspacePreferenceTopicGetResponse.updater()).contains("updater") } @@ -72,6 +74,7 @@ internal class WorkspacePreferenceTopicGetResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicListResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicListResponseTest.kt index 3b2402c7..c6827501 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicListResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicListResponseTest.kt @@ -33,6 +33,7 @@ internal class WorkspacePreferenceTopicListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) @@ -57,6 +58,7 @@ internal class WorkspacePreferenceTopicListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) @@ -85,6 +87,7 @@ internal class WorkspacePreferenceTopicListResponseTest { ) .updated("updated") .creator("creator") + .description("description") .updater("updater") .build() ) diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequestTest.kt index 6b973798..9adacb9f 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/WorkspacePreferenceTopicReplaceRequestTest.kt @@ -21,6 +21,7 @@ internal class WorkspacePreferenceTopicReplaceRequestTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -35,6 +36,7 @@ internal class WorkspacePreferenceTopicReplaceRequestTest { assertThat(workspacePreferenceTopicReplaceRequest.name()).isEqualTo("name") assertThat(workspacePreferenceTopicReplaceRequest.allowedPreferences().getOrNull()) .containsExactly(WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE) + assertThat(workspacePreferenceTopicReplaceRequest.description()).contains("description") assertThat(workspacePreferenceTopicReplaceRequest.includeUnsubscribeHeader()).contains(true) assertThat(workspacePreferenceTopicReplaceRequest.routingOptions().getOrNull()) .containsExactly(ChannelClassification.DIRECT_MESSAGE) @@ -56,6 +58,7 @@ internal class WorkspacePreferenceTopicReplaceRequestTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicCreateParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicCreateParamsTest.kt index 3b2c1a40..f04922d0 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicCreateParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicCreateParamsTest.kt @@ -21,6 +21,7 @@ internal class TopicCreateParamsTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -67,6 +68,7 @@ internal class TopicCreateParamsTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -88,6 +90,7 @@ internal class TopicCreateParamsTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( diff --git a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicReplaceParamsTest.kt index 0aa7116d..2183238f 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicReplaceParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/workspacepreferences/topics/TopicReplaceParamsTest.kt @@ -22,6 +22,7 @@ internal class TopicReplaceParamsTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -71,6 +72,7 @@ internal class TopicReplaceParamsTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -92,6 +94,7 @@ internal class TopicReplaceParamsTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsyncTest.kt index 0518f0f4..dfae2fbb 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/WorkspacePreferenceServiceAsyncTest.kt @@ -4,6 +4,7 @@ package com.courier.services.async import com.courier.client.okhttp.CourierOkHttpClientAsync import com.courier.models.ChannelClassification +import com.courier.models.workspacepreferences.PublishPreferencesRequest import com.courier.models.workspacepreferences.WorkspacePreferenceCreateRequest import com.courier.models.workspacepreferences.WorkspacePreferenceReplaceParams import com.courier.models.workspacepreferences.WorkspacePreferenceReplaceRequest @@ -22,6 +23,7 @@ internal class WorkspacePreferenceServiceAsyncTest { workspacePreferenceServiceAsync.create( WorkspacePreferenceCreateRequest.builder() .name("Account Notifications") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -73,7 +75,14 @@ internal class WorkspacePreferenceServiceAsyncTest { val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() val workspacePreferenceServiceAsync = client.workspacePreferences() - val publishPreferencesResponseFuture = workspacePreferenceServiceAsync.publish() + val publishPreferencesResponseFuture = + workspacePreferenceServiceAsync.publish( + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + ) val publishPreferencesResponse = publishPreferencesResponseFuture.get() publishPreferencesResponse.validate() @@ -92,6 +101,7 @@ internal class WorkspacePreferenceServiceAsyncTest { .workspacePreferenceReplaceRequest( WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/users/PreferenceServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/users/PreferenceServiceAsyncTest.kt index c4207499..09734102 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/users/PreferenceServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/users/PreferenceServiceAsyncTest.kt @@ -5,6 +5,8 @@ package com.courier.services.async.users import com.courier.client.okhttp.CourierOkHttpClientAsync import com.courier.models.ChannelClassification import com.courier.models.PreferenceStatus +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkUpdateParams import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveTopicParams @@ -29,6 +31,68 @@ internal class PreferenceServiceAsyncTest { preference.validate() } + @Disabled("Mock server tests are disabled") + @Test + fun bulkReplace() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val preferenceServiceAsync = client.users().preferences() + + val responseFuture = + preferenceServiceAsync.bulkReplace( + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun bulkUpdate() { + val client = CourierOkHttpClientAsync.builder().apiKey("My API Key").build() + val preferenceServiceAsync = client.users().preferences() + + val responseFuture = + preferenceServiceAsync.bulkUpdate( + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build() + ) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + @Disabled("Mock server tests are disabled") @Test fun deleteTopic() { diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/workspacepreferences/TopicServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/workspacepreferences/TopicServiceAsyncTest.kt index edad21f0..81463825 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/workspacepreferences/TopicServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/workspacepreferences/TopicServiceAsyncTest.kt @@ -35,6 +35,7 @@ internal class TopicServiceAsyncTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -112,6 +113,7 @@ internal class TopicServiceAsyncTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/WorkspacePreferenceServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/WorkspacePreferenceServiceTest.kt index d104a6f6..0bc07a7f 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/WorkspacePreferenceServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/WorkspacePreferenceServiceTest.kt @@ -4,6 +4,7 @@ package com.courier.services.blocking import com.courier.client.okhttp.CourierOkHttpClient import com.courier.models.ChannelClassification +import com.courier.models.workspacepreferences.PublishPreferencesRequest import com.courier.models.workspacepreferences.WorkspacePreferenceCreateRequest import com.courier.models.workspacepreferences.WorkspacePreferenceReplaceParams import com.courier.models.workspacepreferences.WorkspacePreferenceReplaceRequest @@ -22,6 +23,7 @@ internal class WorkspacePreferenceServiceTest { workspacePreferenceService.create( WorkspacePreferenceCreateRequest.builder() .name("Account Notifications") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() @@ -67,7 +69,14 @@ internal class WorkspacePreferenceServiceTest { val client = CourierOkHttpClient.builder().apiKey("My API Key").build() val workspacePreferenceService = client.workspacePreferences() - val publishPreferencesResponse = workspacePreferenceService.publish() + val publishPreferencesResponse = + workspacePreferenceService.publish( + PublishPreferencesRequest.builder() + .brandId("brand_id") + .description("description") + .heading("heading") + .build() + ) publishPreferencesResponse.validate() } @@ -85,6 +94,7 @@ internal class WorkspacePreferenceServiceTest { .workspacePreferenceReplaceRequest( WorkspacePreferenceReplaceRequest.builder() .name("name") + .description("description") .hasCustomRouting(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/users/PreferenceServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/users/PreferenceServiceTest.kt index ad2bff4b..732a33a1 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/users/PreferenceServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/users/PreferenceServiceTest.kt @@ -5,6 +5,8 @@ package com.courier.services.blocking.users import com.courier.client.okhttp.CourierOkHttpClient import com.courier.models.ChannelClassification import com.courier.models.PreferenceStatus +import com.courier.models.users.preferences.PreferenceBulkReplaceParams +import com.courier.models.users.preferences.PreferenceBulkUpdateParams import com.courier.models.users.preferences.PreferenceDeleteTopicParams import com.courier.models.users.preferences.PreferenceRetrieveParams import com.courier.models.users.preferences.PreferenceRetrieveTopicParams @@ -28,6 +30,66 @@ internal class PreferenceServiceTest { preference.validate() } + @Disabled("Mock server tests are disabled") + @Test + fun bulkReplace() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val preferenceService = client.users().preferences() + + val response = + preferenceService.bulkReplace( + PreferenceBulkReplaceParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkReplaceParams.Topic.builder() + .status(PreferenceBulkReplaceParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .build() + ) + + response.validate() + } + + @Disabled("Mock server tests are disabled") + @Test + fun bulkUpdate() { + val client = CourierOkHttpClient.builder().apiKey("My API Key").build() + val preferenceService = client.users().preferences() + + val response = + preferenceService.bulkUpdate( + PreferenceBulkUpdateParams.builder() + .userId("user_id") + .tenantId("tenant_id") + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_IN) + .topicId("74Q4QGFBEX481DP6JRPMV751H4XT") + .addCustomRouting(ChannelClassification.INBOX) + .addCustomRouting(ChannelClassification.EMAIL) + .hasCustomRouting(true) + .build() + ) + .addTopic( + PreferenceBulkUpdateParams.Topic.builder() + .status(PreferenceBulkUpdateParams.Topic.Status.OPTED_OUT) + .topicId("5Q4QGFBEX481DP6JRPMV751H4YU") + .addCustomRouting(ChannelClassification.DIRECT_MESSAGE) + .hasCustomRouting(true) + .build() + ) + .build() + ) + + response.validate() + } + @Disabled("Mock server tests are disabled") @Test fun deleteTopic() { diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/workspacepreferences/TopicServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/workspacepreferences/TopicServiceTest.kt index c77297af..e70923ec 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/workspacepreferences/TopicServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/workspacepreferences/TopicServiceTest.kt @@ -35,6 +35,7 @@ internal class TopicServiceTest { .addAllowedPreference( WorkspacePreferenceTopicCreateRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData( @@ -106,6 +107,7 @@ internal class TopicServiceTest { .addAllowedPreference( WorkspacePreferenceTopicReplaceRequest.AllowedPreference.SNOOZE ) + .description("description") .includeUnsubscribeHeader(true) .addRoutingOption(ChannelClassification.DIRECT_MESSAGE) .topicData(