diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f3ab3a80..81e5e657 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.26.0" + ".": "4.27.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 6f303f16..fbe74a9c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 145 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-31abe25287f6885a9e18e84b9317abcb36a9fff5f694feb7a4353c5622d93730.yml -openapi_spec_hash: 65d48382e29817ef7b89e70b20bf8d4d -config_hash: 3eb0070d128aef7a6da16173f7050177 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-82881993f19c5fac9ac662f1a516e5b54bd7c6655d07f29a3779dfb0286cafd3.yml +openapi_spec_hash: 92f4c510a5a15d091036d70caa8ee573 +config_hash: 768b0f5ada2bf01cf2659d5dbbad1fa0 diff --git a/CHANGELOG.md b/CHANGELOG.md index dc09f8c0..75dd3764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 4.27.0 (2026-08-10) + +Full Changelog: [v4.26.0...v4.27.0](https://github.com/trycourier/courier-java/compare/v4.26.0...v4.27.0) + +### Features + +* Merge pull request [#185](https://github.com/trycourier/courier-java/issues/185) from trycourier/geraldosilva/c-19821-notifications-alias-v2 ([cd5d43a](https://github.com/trycourier/courier-java/commit/cd5d43ae82d645c083527d1a81de4a513c446e8e)) + ## 4.26.0 (2026-08-04) Full Changelog: [v4.25.0...v4.26.0](https://github.com/trycourier/courier-java/compare/v4.25.0...v4.26.0) diff --git a/build.gradle.kts b/build.gradle.kts index d0475401..1439890a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.courier" - version = "4.26.0" // x-release-please-version + version = "4.27.0" // x-release-please-version } subprojects { diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt index f0106217..b591e428 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationReplaceParams.kt @@ -27,7 +27,8 @@ private constructor( /** * Request body for replacing a notification template. Same shape as create. All fields required - * (PUT = full replacement). + * (PUT = full replacement), except `alias`, whose omission means "leave the existing aliases + * alone". */ fun notificationTemplateUpdateRequest(): NotificationTemplateUpdateRequest = notificationTemplateUpdateRequest @@ -80,7 +81,8 @@ private constructor( /** * Request body for replacing a notification template. Same shape as create. All fields - * required (PUT = full replacement). + * required (PUT = full replacement), except `alias`, whose omission means "leave the + * existing aliases alone". */ fun notificationTemplateUpdateRequest( notificationTemplateUpdateRequest: NotificationTemplateUpdateRequest diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateAlias.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateAlias.kt new file mode 100644 index 00000000..c034c987 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateAlias.kt @@ -0,0 +1,237 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.BaseDeserializer +import com.courier.core.BaseSerializer +import com.courier.core.JsonValue +import com.courier.core.allMaxBy +import com.courier.core.getOrThrow +import com.courier.core.toImmutable +import com.courier.errors.CourierInvalidDataException +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.util.Objects +import java.util.Optional + +/** + * A template's send-time alias as returned by a read, omitted entirely when it has none. Usually a + * single string; an array for a template that resolves from several aliases, which writes through + * this API can no longer produce — only templates predating that restriction, or aliases attached + * outside this API, hold more than one. + */ +@JsonDeserialize(using = NotificationTemplateAlias.Deserializer::class) +@JsonSerialize(using = NotificationTemplateAlias.Serializer::class) +class NotificationTemplateAlias +private constructor( + private val string: String? = null, + private val strings: List? = null, + private val _json: JsonValue? = null, +) { + + fun string(): Optional = Optional.ofNullable(string) + + fun strings(): Optional> = Optional.ofNullable(strings) + + fun isString(): Boolean = string != null + + fun isStrings(): Boolean = strings != null + + fun asString(): String = string.getOrThrow("string") + + fun asStrings(): List = strings.getOrThrow("strings") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.courier.core.JsonValue; + * import java.util.Optional; + * + * Optional result = notificationTemplateAlias.accept(new NotificationTemplateAlias.Visitor>() { + * @Override + * public Optional visitString(String string) { + * return Optional.of(string.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws CourierInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + strings != null -> visitor.visitStrings(strings) + else -> visitor.unknown(_json) + } + + 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(): NotificationTemplateAlias = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitStrings(strings: List) {} + } + ) + 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 = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitStrings(strings: List) = strings.size + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateAlias && + string == other.string && + strings == other.strings + } + + override fun hashCode(): Int = Objects.hash(string, strings) + + override fun toString(): String = + when { + string != null -> "NotificationTemplateAlias{string=$string}" + strings != null -> "NotificationTemplateAlias{strings=$strings}" + _json != null -> "NotificationTemplateAlias{_unknown=$_json}" + else -> throw IllegalStateException("Invalid NotificationTemplateAlias") + } + + companion object { + + @JvmStatic fun ofString(string: String) = NotificationTemplateAlias(string = string) + + @JvmStatic + fun ofStrings(strings: List) = + NotificationTemplateAlias(strings = strings.toImmutable()) + } + + /** + * An interface that defines how to map each variant of [NotificationTemplateAlias] to a value + * of type [T]. + */ + interface Visitor { + + fun visitString(string: String): T + + fun visitStrings(strings: List): T + + /** + * Maps an unknown variant of [NotificationTemplateAlias] to a value of type [T]. + * + * An instance of [NotificationTemplateAlias] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws CourierInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw CourierInvalidDataException("Unknown NotificationTemplateAlias: $json") + } + } + + internal class Deserializer : + BaseDeserializer(NotificationTemplateAlias::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): NotificationTemplateAlias { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + NotificationTemplateAlias(string = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>())?.let { + NotificationTemplateAlias(strings = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> NotificationTemplateAlias(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(NotificationTemplateAlias::class) { + + override fun serialize( + value: NotificationTemplateAlias, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.strings != null -> generator.writeObject(value.strings) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid NotificationTemplateAlias") + } + } + } +} diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt index 25fd0828..a475d819 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequest.kt @@ -22,7 +22,7 @@ import kotlin.jvm.optionals.getOrNull class NotificationTemplateCreateRequest @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val notification: JsonField, + private val notification: JsonField, private val state: JsonField, private val additionalProperties: MutableMap, ) { @@ -31,18 +31,17 @@ private constructor( private constructor( @JsonProperty("notification") @ExcludeMissing - notification: JsonField = JsonMissing.of(), + notification: JsonField = JsonMissing.of(), @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), ) : this(notification, state, mutableMapOf()) /** - * Core template fields used in POST and PUT request bodies (nested under a `notification` key) - * and returned at the top level in responses. + * Template fields accepted in POST and PUT request bodies, nested under a `notification` key. * * @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 notification(): NotificationTemplatePayload = notification.getRequired("notification") + fun notification(): NotificationTemplateWritePayload = notification.getRequired("notification") /** * Template state after creation. Case-insensitive input, normalized to uppercase in the @@ -60,7 +59,7 @@ private constructor( */ @JsonProperty("notification") @ExcludeMissing - fun _notification(): JsonField = notification + fun _notification(): JsonField = notification /** * Returns the raw JSON value of [state]. @@ -98,7 +97,7 @@ private constructor( /** A builder for [NotificationTemplateCreateRequest]. */ class Builder internal constructor() { - private var notification: JsonField? = null + private var notification: JsonField? = null private var state: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -112,20 +111,20 @@ private constructor( } /** - * Core template fields used in POST and PUT request bodies (nested under a `notification` - * key) and returned at the top level in responses. + * Template fields accepted in POST and PUT request bodies, nested under a `notification` + * key. */ - fun notification(notification: NotificationTemplatePayload) = + fun notification(notification: NotificationTemplateWritePayload) = notification(JsonField.of(notification)) /** * Sets [Builder.notification] to an arbitrary JSON value. * * You should usually call [Builder.notification] with a well-typed - * [NotificationTemplatePayload] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. + * [NotificationTemplateWritePayload] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. */ - fun notification(notification: JsonField) = apply { + fun notification(notification: JsonField) = apply { this.notification = notification } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateResponse.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateResponse.kt index c5a66403..e38f6431 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateResponse.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateResponse.kt @@ -38,6 +38,7 @@ private constructor( private val created: JsonField, private val creator: JsonField, private val state: JsonField, + private val alias: JsonField, private val updated: JsonField, private val updater: JsonField, private val additionalProperties: MutableMap, @@ -63,6 +64,9 @@ private constructor( @JsonProperty("created") @ExcludeMissing created: JsonField = JsonMissing.of(), @JsonProperty("creator") @ExcludeMissing creator: JsonField = JsonMissing.of(), @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + @JsonProperty("alias") + @ExcludeMissing + alias: JsonField = JsonMissing.of(), @JsonProperty("updated") @ExcludeMissing updated: JsonField = JsonMissing.of(), @JsonProperty("updater") @ExcludeMissing updater: JsonField = JsonMissing.of(), ) : this( @@ -76,6 +80,7 @@ private constructor( created, creator, state, + alias, updated, updater, mutableMapOf(), @@ -172,6 +177,17 @@ private constructor( */ fun state(): State = state.getRequired("state") + /** + * A template's send-time alias as returned by a read, omitted entirely when it has none. + * Usually a single string; an array for a template that resolves from several aliases, which + * writes through this API can no longer produce — only templates predating that restriction, or + * aliases attached outside this API, hold more than one. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun alias(): Optional = alias.getOptional("alias") + /** * Epoch milliseconds of last update. * @@ -264,6 +280,15 @@ private constructor( */ @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + /** + * Returns the raw JSON value of [alias]. + * + * Unlike [alias], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("alias") + @ExcludeMissing + fun _alias(): JsonField = alias + /** * Returns the raw JSON value of [updated]. * @@ -325,6 +350,7 @@ private constructor( private var created: JsonField? = null private var creator: JsonField? = null private var state: JsonField? = null + private var alias: JsonField = JsonMissing.of() private var updated: JsonField = JsonMissing.of() private var updater: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -341,6 +367,7 @@ private constructor( created = notificationTemplateResponse.created creator = notificationTemplateResponse.creator state = notificationTemplateResponse.state + alias = notificationTemplateResponse.alias updated = notificationTemplateResponse.updated updater = notificationTemplateResponse.updater additionalProperties = notificationTemplateResponse.additionalProperties.toMutableMap() @@ -492,6 +519,30 @@ private constructor( */ fun state(state: JsonField) = apply { this.state = state } + /** + * A template's send-time alias as returned by a read, omitted entirely when it has none. + * Usually a single string; an array for a template that resolves from several aliases, + * which writes through this API can no longer produce — only templates predating that + * restriction, or aliases attached outside this API, hold more than one. + */ + fun alias(alias: NotificationTemplateAlias) = alias(JsonField.of(alias)) + + /** + * Sets [Builder.alias] to an arbitrary JSON value. + * + * You should usually call [Builder.alias] with a well-typed [NotificationTemplateAlias] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun alias(alias: JsonField) = apply { this.alias = alias } + + /** Alias for calling [alias] with `NotificationTemplateAlias.ofString(string)`. */ + fun alias(string: String) = alias(NotificationTemplateAlias.ofString(string)) + + /** Alias for calling [alias] with `NotificationTemplateAlias.ofStrings(strings)`. */ + fun aliasOfStrings(strings: List) = + alias(NotificationTemplateAlias.ofStrings(strings)) + /** Epoch milliseconds of last update. */ fun updated(updated: Long) = updated(JsonField.of(updated)) @@ -566,6 +617,7 @@ private constructor( checkRequired("created", created), checkRequired("creator", creator), checkRequired("state", state), + alias, updated, updater, additionalProperties.toMutableMap(), @@ -597,6 +649,7 @@ private constructor( created() creator() state().validate() + alias().ifPresent { it.validate() } updated() updater() validated = true @@ -627,6 +680,7 @@ private constructor( (if (created.asKnown().isPresent) 1 else 0) + (if (creator.asKnown().isPresent) 1 else 0) + (state.asKnown().getOrNull()?.validity() ?: 0) + + (alias.asKnown().getOrNull()?.validity() ?: 0) + (if (updated.asKnown().isPresent) 1 else 0) + (if (updater.asKnown().isPresent) 1 else 0) @@ -781,6 +835,7 @@ private constructor( created == other.created && creator == other.creator && state == other.state && + alias == other.alias && updated == other.updated && updater == other.updater && additionalProperties == other.additionalProperties @@ -798,6 +853,7 @@ private constructor( created, creator, state, + alias, updated, updater, additionalProperties, @@ -807,5 +863,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "NotificationTemplateResponse{brand=$brand, content=$content, name=$name, routing=$routing, subscription=$subscription, tags=$tags, id=$id, created=$created, creator=$creator, state=$state, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" + "NotificationTemplateResponse{brand=$brand, content=$content, name=$name, routing=$routing, subscription=$subscription, tags=$tags, id=$id, created=$created, creator=$creator, state=$state, alias=$alias, updated=$updated, updater=$updater, additionalProperties=$additionalProperties}" } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt index 269620dc..d99642cc 100644 --- a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequest.kt @@ -20,12 +20,13 @@ import kotlin.jvm.optionals.getOrNull /** * Request body for replacing a notification template. Same shape as create. All fields required - * (PUT = full replacement). + * (PUT = full replacement), except `alias`, whose omission means "leave the existing aliases + * alone". */ class NotificationTemplateUpdateRequest @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val notification: JsonField, + private val notification: JsonField, private val state: JsonField, private val additionalProperties: MutableMap, ) { @@ -34,18 +35,17 @@ private constructor( private constructor( @JsonProperty("notification") @ExcludeMissing - notification: JsonField = JsonMissing.of(), + notification: JsonField = JsonMissing.of(), @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), ) : this(notification, state, mutableMapOf()) /** - * Core template fields used in POST and PUT request bodies (nested under a `notification` key) - * and returned at the top level in responses. + * Template fields accepted in POST and PUT request bodies, nested under a `notification` key. * * @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 notification(): NotificationTemplatePayload = notification.getRequired("notification") + fun notification(): NotificationTemplateWritePayload = notification.getRequired("notification") /** * Template state after update. Case-insensitive input, normalized to uppercase in the response. @@ -63,7 +63,7 @@ private constructor( */ @JsonProperty("notification") @ExcludeMissing - fun _notification(): JsonField = notification + fun _notification(): JsonField = notification /** * Returns the raw JSON value of [state]. @@ -101,7 +101,7 @@ private constructor( /** A builder for [NotificationTemplateUpdateRequest]. */ class Builder internal constructor() { - private var notification: JsonField? = null + private var notification: JsonField? = null private var state: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -115,20 +115,20 @@ private constructor( } /** - * Core template fields used in POST and PUT request bodies (nested under a `notification` - * key) and returned at the top level in responses. + * Template fields accepted in POST and PUT request bodies, nested under a `notification` + * key. */ - fun notification(notification: NotificationTemplatePayload) = + fun notification(notification: NotificationTemplateWritePayload) = notification(JsonField.of(notification)) /** * Sets [Builder.notification] to an arbitrary JSON value. * * You should usually call [Builder.notification] with a well-typed - * [NotificationTemplatePayload] value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. + * [NotificationTemplateWritePayload] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. */ - fun notification(notification: JsonField) = apply { + fun notification(notification: JsonField) = apply { this.notification = notification } diff --git a/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateWritePayload.kt b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateWritePayload.kt new file mode 100644 index 00000000..fe459895 --- /dev/null +++ b/courier-java-core/src/main/kotlin/com/courier/models/notifications/NotificationTemplateWritePayload.kt @@ -0,0 +1,484 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +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.ElementalContent +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 + +/** Template fields accepted in POST and PUT request bodies, nested under a `notification` key. */ +class NotificationTemplateWritePayload +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val brand: JsonField, + private val content: JsonField, + private val name: JsonField, + private val routing: JsonField, + private val subscription: JsonField, + private val tags: JsonField>, + private val alias: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("brand") + @ExcludeMissing + brand: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("routing") + @ExcludeMissing + routing: JsonField = JsonMissing.of(), + @JsonProperty("subscription") + @ExcludeMissing + subscription: JsonField = JsonMissing.of(), + @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(), + @JsonProperty("alias") @ExcludeMissing alias: JsonField = JsonMissing.of(), + ) : this(brand, content, name, routing, subscription, tags, alias, mutableMapOf()) + + fun toNotificationTemplatePayload(): NotificationTemplatePayload = + NotificationTemplatePayload.builder() + .brand(brand) + .content(content) + .name(name) + .routing(routing) + .subscription(subscription) + .tags(tags) + .build() + + /** + * Brand reference, or null for no brand. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun brand(): Optional = brand.getOptional("brand") + + /** + * Elemental content definition. + * + * @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 content(): ElementalContent = content.getRequired("content") + + /** + * Display name for the template. + * + * @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 name(): String = name.getRequired("name") + + /** + * Routing strategy reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun routing(): Optional = routing.getOptional("routing") + + /** + * Subscription topic reference, or null for none. + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun subscription(): Optional = + subscription.getOptional("subscription") + + /** + * Tags for categorization. Send empty array for none. + * + * @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 tags(): List = tags.getRequired("tags") + + /** + * Send-time alias for this template — the value you pass as `event` to POST /send. Writes + * accept a single alias only. Optional, with three distinct meanings. Omit it to leave any + * existing aliases untouched. Send a string to make this the template's only alias — a template + * that already resolved from several aliases keeps just this one and the rest are detached. + * Send null to remove every alias from the template. An alias may not be claimed by another + * template — doing so returns 409 — and may not begin with "tenant/". + * + * @throws CourierInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun alias(): Optional = alias.getOptional("alias") + + /** + * Returns the raw JSON value of [brand]. + * + * Unlike [brand], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("brand") + @ExcludeMissing + fun _brand(): JsonField = brand + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [routing]. + * + * Unlike [routing], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("routing") + @ExcludeMissing + fun _routing(): JsonField = routing + + /** + * Returns the raw JSON value of [subscription]. + * + * Unlike [subscription], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("subscription") + @ExcludeMissing + fun _subscription(): JsonField = subscription + + /** + * Returns the raw JSON value of [tags]. + * + * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags + + /** + * Returns the raw JSON value of [alias]. + * + * Unlike [alias], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("alias") @ExcludeMissing fun _alias(): JsonField = alias + + @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 + * [NotificationTemplateWritePayload]. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NotificationTemplateWritePayload]. */ + class Builder internal constructor() { + + private var brand: JsonField? = null + private var content: JsonField? = null + private var name: JsonField? = null + private var routing: JsonField? = null + private var subscription: JsonField? = null + private var tags: JsonField>? = null + private var alias: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(notificationTemplateWritePayload: NotificationTemplateWritePayload) = + apply { + brand = notificationTemplateWritePayload.brand + content = notificationTemplateWritePayload.content + name = notificationTemplateWritePayload.name + routing = notificationTemplateWritePayload.routing + subscription = notificationTemplateWritePayload.subscription + tags = notificationTemplateWritePayload.tags.map { it.toMutableList() } + alias = notificationTemplateWritePayload.alias + additionalProperties = + notificationTemplateWritePayload.additionalProperties.toMutableMap() + } + + /** Brand reference, or null for no brand. */ + fun brand(brand: NotificationTemplatePayload.Brand?) = brand(JsonField.ofNullable(brand)) + + /** Alias for calling [Builder.brand] with `brand.orElse(null)`. */ + fun brand(brand: Optional) = brand(brand.getOrNull()) + + /** + * Sets [Builder.brand] to an arbitrary JSON value. + * + * You should usually call [Builder.brand] with a well-typed + * [NotificationTemplatePayload.Brand] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun brand(brand: JsonField) = apply { + this.brand = brand + } + + /** Elemental content definition. */ + fun content(content: ElementalContent) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [ElementalContent] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** Display name for the template. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Routing strategy reference, or null for none. */ + fun routing(routing: NotificationTemplatePayload.Routing?) = + routing(JsonField.ofNullable(routing)) + + /** Alias for calling [Builder.routing] with `routing.orElse(null)`. */ + fun routing(routing: Optional) = + routing(routing.getOrNull()) + + /** + * Sets [Builder.routing] to an arbitrary JSON value. + * + * You should usually call [Builder.routing] with a well-typed + * [NotificationTemplatePayload.Routing] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun routing(routing: JsonField) = apply { + this.routing = routing + } + + /** Subscription topic reference, or null for none. */ + fun subscription(subscription: NotificationTemplatePayload.Subscription?) = + subscription(JsonField.ofNullable(subscription)) + + /** Alias for calling [Builder.subscription] with `subscription.orElse(null)`. */ + fun subscription(subscription: Optional) = + subscription(subscription.getOrNull()) + + /** + * Sets [Builder.subscription] to an arbitrary JSON value. + * + * You should usually call [Builder.subscription] with a well-typed + * [NotificationTemplatePayload.Subscription] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun subscription(subscription: JsonField) = + apply { + this.subscription = subscription + } + + /** Tags for categorization. Send empty array for none. */ + fun tags(tags: List) = tags(JsonField.of(tags)) + + /** + * Sets [Builder.tags] to an arbitrary JSON value. + * + * You should usually call [Builder.tags] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tags(tags: JsonField>) = apply { + this.tags = tags.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [tags]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: String) = apply { + tags = (tags ?: JsonField.of(mutableListOf())).also { checkKnown("tags", it).add(tag) } + } + + /** + * Send-time alias for this template — the value you pass as `event` to POST /send. Writes + * accept a single alias only. Optional, with three distinct meanings. Omit it to leave any + * existing aliases untouched. Send a string to make this the template's only alias — a + * template that already resolved from several aliases keeps just this one and the rest are + * detached. Send null to remove every alias from the template. An alias may not be claimed + * by another template — doing so returns 409 — and may not begin with "tenant/". + */ + fun alias(alias: String?) = alias(JsonField.ofNullable(alias)) + + /** Alias for calling [Builder.alias] with `alias.orElse(null)`. */ + fun alias(alias: Optional) = alias(alias.getOrNull()) + + /** + * Sets [Builder.alias] to an arbitrary JSON value. + * + * You should usually call [Builder.alias] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun alias(alias: JsonField) = apply { this.alias = alias } + + 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 [NotificationTemplateWritePayload]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .brand() + * .content() + * .name() + * .routing() + * .subscription() + * .tags() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): NotificationTemplateWritePayload = + NotificationTemplateWritePayload( + checkRequired("brand", brand), + checkRequired("content", content), + checkRequired("name", name), + checkRequired("routing", routing), + checkRequired("subscription", subscription), + checkRequired("tags", tags).map { it.toImmutable() }, + alias, + 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(): NotificationTemplateWritePayload = apply { + if (validated) { + return@apply + } + + brand().ifPresent { it.validate() } + content().validate() + name() + routing().ifPresent { it.validate() } + subscription().ifPresent { it.validate() } + tags() + alias() + 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 = + (brand.asKnown().getOrNull()?.validity() ?: 0) + + (content.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (routing.asKnown().getOrNull()?.validity() ?: 0) + + (subscription.asKnown().getOrNull()?.validity() ?: 0) + + (tags.asKnown().getOrNull()?.size ?: 0) + + (if (alias.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NotificationTemplateWritePayload && + brand == other.brand && + content == other.content && + name == other.name && + routing == other.routing && + subscription == other.subscription && + tags == other.tags && + alias == other.alias && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(brand, content, name, routing, subscription, tags, alias, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NotificationTemplateWritePayload{brand=$brand, content=$content, name=$name, routing=$routing, subscription=$subscription, tags=$tags, alias=$alias, additionalProperties=$additionalProperties}" +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt index b4011724..0ba9e050 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationCreateParamsTest.kt @@ -19,7 +19,7 @@ internal class NotificationCreateParamsTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -48,6 +48,7 @@ internal class NotificationCreateParamsTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -65,7 +66,7 @@ internal class NotificationCreateParamsTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -94,6 +95,7 @@ internal class NotificationCreateParamsTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -119,7 +121,7 @@ internal class NotificationCreateParamsTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -164,7 +166,7 @@ internal class NotificationCreateParamsTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -193,6 +195,7 @@ internal class NotificationCreateParamsTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -206,7 +209,7 @@ internal class NotificationCreateParamsTest { .isEqualTo( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -235,6 +238,7 @@ internal class NotificationCreateParamsTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -249,7 +253,7 @@ internal class NotificationCreateParamsTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -286,7 +290,7 @@ internal class NotificationCreateParamsTest { .isEqualTo( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt index 39e34a6f..b6f5f240 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationReplaceParamsTest.kt @@ -17,7 +17,7 @@ internal class NotificationReplaceParamsTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -41,6 +41,7 @@ internal class NotificationReplaceParamsTest { .build() ) .addTag("updated") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.PUBLISHED) @@ -57,7 +58,7 @@ internal class NotificationReplaceParamsTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -96,7 +97,7 @@ internal class NotificationReplaceParamsTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -120,6 +121,7 @@ internal class NotificationReplaceParamsTest { .build() ) .addTag("updated") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.PUBLISHED) @@ -133,7 +135,7 @@ internal class NotificationReplaceParamsTest { .isEqualTo( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -157,6 +159,7 @@ internal class NotificationReplaceParamsTest { .build() ) .addTag("updated") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.PUBLISHED) @@ -172,7 +175,7 @@ internal class NotificationReplaceParamsTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -204,7 +207,7 @@ internal class NotificationReplaceParamsTest { .isEqualTo( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateAliasTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateAliasTest.kt new file mode 100644 index 00000000..26f718cf --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateAliasTest.kt @@ -0,0 +1,81 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.JsonValue +import com.courier.core.jsonMapper +import com.courier.errors.CourierInvalidDataException +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class NotificationTemplateAliasTest { + + @Test + fun ofString() { + val string = "string" + + val notificationTemplateAlias = NotificationTemplateAlias.ofString(string) + + assertThat(notificationTemplateAlias.string()).contains(string) + assertThat(notificationTemplateAlias.strings()).isEmpty + } + + @Test + fun ofStringRoundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateAlias = NotificationTemplateAlias.ofString("string") + + val roundtrippedNotificationTemplateAlias = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateAlias), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateAlias).isEqualTo(notificationTemplateAlias) + } + + @Test + fun ofStrings() { + val strings = listOf("string") + + val notificationTemplateAlias = NotificationTemplateAlias.ofStrings(strings) + + assertThat(notificationTemplateAlias.string()).isEmpty + assertThat(notificationTemplateAlias.strings()).contains(strings) + } + + @Test + fun ofStringsRoundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateAlias = NotificationTemplateAlias.ofStrings(listOf("string")) + + val roundtrippedNotificationTemplateAlias = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateAlias), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateAlias).isEqualTo(notificationTemplateAlias) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + OBJECT(JsonValue.from(mapOf("invalid" to "object"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val notificationTemplateAlias = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { notificationTemplateAlias.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt index 974768fa..e1b3c92b 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateCreateRequestTest.kt @@ -16,7 +16,7 @@ internal class NotificationTemplateCreateRequestTest { val notificationTemplateCreateRequest = NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -44,6 +44,7 @@ internal class NotificationTemplateCreateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -51,7 +52,7 @@ internal class NotificationTemplateCreateRequestTest { assertThat(notificationTemplateCreateRequest.notification()) .isEqualTo( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -79,6 +80,7 @@ internal class NotificationTemplateCreateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) assertThat(notificationTemplateCreateRequest.state()) @@ -91,7 +93,7 @@ internal class NotificationTemplateCreateRequestTest { val notificationTemplateCreateRequest = NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -119,6 +121,7 @@ internal class NotificationTemplateCreateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateResponseTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateResponseTest.kt index be40fe92..4f39c068 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateResponseTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateResponseTest.kt @@ -42,6 +42,7 @@ internal class NotificationTemplateResponseTest { .created(0L) .creator("creator") .state(NotificationTemplateResponse.State.DRAFT) + .alias("string") .updated(0L) .updater("updater") .build() @@ -78,6 +79,8 @@ internal class NotificationTemplateResponseTest { assertThat(notificationTemplateResponse.creator()).isEqualTo("creator") assertThat(notificationTemplateResponse.state()) .isEqualTo(NotificationTemplateResponse.State.DRAFT) + assertThat(notificationTemplateResponse.alias()) + .contains(NotificationTemplateAlias.ofString("string")) assertThat(notificationTemplateResponse.updated()).contains(0L) assertThat(notificationTemplateResponse.updater()).contains("updater") } @@ -114,6 +117,7 @@ internal class NotificationTemplateResponseTest { .created(0L) .creator("creator") .state(NotificationTemplateResponse.State.DRAFT) + .alias("string") .updated(0L) .updater("updater") .build() diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt index b220db66..99ed45ba 100644 --- a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateUpdateRequestTest.kt @@ -16,7 +16,7 @@ internal class NotificationTemplateUpdateRequestTest { val notificationTemplateUpdateRequest = NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -44,6 +44,7 @@ internal class NotificationTemplateUpdateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.DRAFT) @@ -51,7 +52,7 @@ internal class NotificationTemplateUpdateRequestTest { assertThat(notificationTemplateUpdateRequest.notification()) .isEqualTo( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -79,6 +80,7 @@ internal class NotificationTemplateUpdateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) assertThat(notificationTemplateUpdateRequest.state()) @@ -91,7 +93,7 @@ internal class NotificationTemplateUpdateRequestTest { val notificationTemplateUpdateRequest = NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) .content( ElementalContent.builder() @@ -119,6 +121,7 @@ internal class NotificationTemplateUpdateRequestTest { .build() ) .addTag("string") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.DRAFT) diff --git a/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateWritePayloadTest.kt b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateWritePayloadTest.kt new file mode 100644 index 00000000..7d70c201 --- /dev/null +++ b/courier-java-core/src/test/kotlin/com/courier/models/notifications/NotificationTemplateWritePayloadTest.kt @@ -0,0 +1,114 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.courier.models.notifications + +import com.courier.core.jsonMapper +import com.courier.models.ElementalContent +import com.courier.models.ElementalTextNodeWithType +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class NotificationTemplateWritePayloadTest { + + @Test + fun create() { + val notificationTemplateWritePayload = + NotificationTemplateWritePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + .addTag("string") + .alias("alias") + .build() + + assertThat(notificationTemplateWritePayload.brand()) + .contains(NotificationTemplatePayload.Brand.builder().id("id").build()) + assertThat(notificationTemplateWritePayload.content()) + .isEqualTo( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + assertThat(notificationTemplateWritePayload.name()).isEqualTo("name") + assertThat(notificationTemplateWritePayload.routing()) + .contains( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + assertThat(notificationTemplateWritePayload.subscription()) + .contains( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + assertThat(notificationTemplateWritePayload.tags()).containsExactly("string") + assertThat(notificationTemplateWritePayload.alias()).contains("alias") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val notificationTemplateWritePayload = + NotificationTemplateWritePayload.builder() + .brand(NotificationTemplatePayload.Brand.builder().id("id").build()) + .content( + ElementalContent.builder() + .addElement( + ElementalTextNodeWithType.builder() + .addChannel("string") + .if_("if") + .loop("loop") + .ref("ref") + .type(ElementalTextNodeWithType.Type.TEXT) + .build() + ) + .version("version") + .build() + ) + .name("name") + .routing( + NotificationTemplatePayload.Routing.builder().strategyId("strategy_id").build() + ) + .subscription( + NotificationTemplatePayload.Subscription.builder().topicId("topic_id").build() + ) + .addTag("string") + .alias("alias") + .build() + + val roundtrippedNotificationTemplateWritePayload = + jsonMapper.readValue( + jsonMapper.writeValueAsString(notificationTemplateWritePayload), + jacksonTypeRef(), + ) + + assertThat(roundtrippedNotificationTemplateWritePayload) + .isEqualTo(notificationTemplateWritePayload) + } +} diff --git a/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt index 0d069b1f..3ce702e5 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/async/NotificationServiceAsyncTest.kt @@ -24,6 +24,7 @@ import com.courier.models.notifications.NotificationTemplatePayload import com.courier.models.notifications.NotificationTemplatePublishRequest import com.courier.models.notifications.NotificationTemplateState import com.courier.models.notifications.NotificationTemplateUpdateRequest +import com.courier.models.notifications.NotificationTemplateWritePayload import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -43,7 +44,7 @@ internal class NotificationServiceAsyncTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -72,6 +73,7 @@ internal class NotificationServiceAsyncTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -291,7 +293,7 @@ internal class NotificationServiceAsyncTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder().id("id").build() ) @@ -317,6 +319,7 @@ internal class NotificationServiceAsyncTest { .build() ) .addTag("updated") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.PUBLISHED) diff --git a/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt b/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt index 48e96fcb..13549cc5 100644 --- a/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt +++ b/courier-java-core/src/test/kotlin/com/courier/services/blocking/NotificationServiceTest.kt @@ -24,6 +24,7 @@ import com.courier.models.notifications.NotificationTemplatePayload import com.courier.models.notifications.NotificationTemplatePublishRequest import com.courier.models.notifications.NotificationTemplateState import com.courier.models.notifications.NotificationTemplateUpdateRequest +import com.courier.models.notifications.NotificationTemplateWritePayload import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -43,7 +44,7 @@ internal class NotificationServiceTest { .notificationTemplateCreateRequest( NotificationTemplateCreateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder() .id("bnd_01kx4mrd0pfzw8wt7pn7p2fzag") @@ -72,6 +73,7 @@ internal class NotificationServiceTest { ) .addTag("onboarding") .addTag("welcome") + .alias("welcome") .build() ) .state(NotificationTemplateCreateRequest.State.DRAFT) @@ -275,7 +277,7 @@ internal class NotificationServiceTest { .notificationTemplateUpdateRequest( NotificationTemplateUpdateRequest.builder() .notification( - NotificationTemplatePayload.builder() + NotificationTemplateWritePayload.builder() .brand( NotificationTemplatePayload.Brand.builder().id("id").build() ) @@ -301,6 +303,7 @@ internal class NotificationServiceTest { .build() ) .addTag("updated") + .alias("alias") .build() ) .state(NotificationTemplateUpdateRequest.State.PUBLISHED)