diff --git a/.gitignore b/.gitignore index a5c2716..627ce37 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ mvnw.cmd build/ !**/src/main/**/build/ !**/src/test/**/build/ - +**/out/** ### VS Code ### .vscode/ /.mvn/ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2924c1a..de62f05 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] com-fasterxml-jackson-core-jackson-core = "2.15.2" com-fasterxml-jackson-core-jackson-databind = "2.15.2" +com-fasterxml-jackson-core-jackson-modules-parameter-names = "2.15.2" org-jetbrains-annotations = "24.1.0" org-projectlombok-lombok = "1.18.26" org-springframework-boot-spring-boot-autoconfigure = "3.0.7" @@ -22,12 +23,15 @@ org-springframework-cloud-spring-cloud-starter-openfeign = "4.0.2" [libraries] com-fasterxml-jackson-core-jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "com-fasterxml-jackson-core-jackson-core" } com-fasterxml-jackson-core-jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "com-fasterxml-jackson-core-jackson-databind" } +com-fasterxml-jackson-core-jackson-modules-parameter-names = { module = "com.fasterxml.jackson.module:jackson-module-parameter-names", version.ref = "com-fasterxml-jackson-core-jackson-modules-parameter-names" } org-jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "org-jetbrains-annotations" } org-projectlombok-lombok = { module = "org.projectlombok:lombok", version.ref = "org-projectlombok-lombok" } org-springframework-boot-spring-boot-autoconfigure = { module = "org.springframework.boot:spring-boot-autoconfigure", version.ref = "org-springframework-boot-spring-boot-autoconfigure" } org-springframework-boot-spring-boot-devtools = { module = "org.springframework.boot:spring-boot-devtools", version.ref = "org-springframework-boot-spring-boot-devtools" } org-springframework-boot-spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "org-springframework-boot-spring-boot-starter-test" } org-springframework-hateoas-spring-hateoas = { module = "org.springframework.hateoas:spring-hateoas", version.ref = "org-springframework-hateoas-spring-hateoas" } +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version = "5.8.1" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version = "5.8.1" } com-odeyalo-sonata-suite = { module = "com.odeyalo.sonata:suite", version.ref = "com-odeyalo-sonata-suite" } com-playtika-reactivefeign-feign-reactor-spring-cloud-starter = { module = "com.playtika.reactivefeign:feign-reactor-spring-cloud-starter", version.ref = "com-playtika-reactivefeign-feign-reactor-spring-cloud-starter" } io-projectreactor-reactor-test = { module = "io.projectreactor:reactor-test", version.ref = "io-projectreactor-reactor-test" } diff --git a/suite-brokers/build.gradle.kts b/suite-brokers/build.gradle.kts index a555ca2..d3ab8e0 100644 --- a/suite-brokers/build.gradle.kts +++ b/suite-brokers/build.gradle.kts @@ -7,10 +7,17 @@ dependencies { api(libs.org.projectlombok.lombok) api(libs.com.odeyalo.sonata.suite) annotationProcessor(libs.org.projectlombok.lombok) + + testImplementation(libs.junit.jupiter.api) + testRuntimeOnly(libs.junit.jupiter.engine) + + testImplementation(libs.com.fasterxml.jackson.core.jackson.core) + testImplementation(libs.com.fasterxml.jackson.core.jackson.databind) + testImplementation(libs.com.fasterxml.jackson.core.jackson.modules.parameter.names) } group = "com.odeyalo.sonata.suite" -version = "0.0.10" +version = "0.0.11" description = "suite-brokers" tasks.withType() { diff --git a/suite-brokers/lombok.config b/suite-brokers/lombok.config new file mode 100644 index 0000000..11d9fba --- /dev/null +++ b/suite-brokers/lombok.config @@ -0,0 +1 @@ +lombok.copyableAnnotations+=com.fasterxml.jackson.annotation.JsonProperty \ No newline at end of file diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/AbstractEvent.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/AbstractEvent.java index 0aa5273..97a21b2 100644 --- a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/AbstractEvent.java +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/AbstractEvent.java @@ -1,11 +1,13 @@ package com.odeyalo.sonata.suite.brokers.events; import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.EqualsAndHashCode; import lombok.Getter; import java.util.UUID; @Getter +@EqualsAndHashCode public abstract class AbstractEvent implements SonataEvent, EventTypeProvider { protected String id; protected long creationTime; diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/GeneratedPlaylistType.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/GeneratedPlaylistType.java new file mode 100644 index 0000000..6fa355c --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/GeneratedPlaylistType.java @@ -0,0 +1,5 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen; + +public enum GeneratedPlaylistType { + ON_REPEAT +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistImagesGeneratedEvent.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistImagesGeneratedEvent.java new file mode 100644 index 0000000..189516a --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistImagesGeneratedEvent.java @@ -0,0 +1,38 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.GenerativePlaylistEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.PlaylistImagesGeneratedPayload; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.PlaylistMetaGeneratedPayload; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +@EqualsAndHashCode(callSuper = true) +@Value +@JsonIgnoreProperties(ignoreUnknown = true) +public class PlaylistImagesGeneratedEvent extends GenerativePlaylistEvent { + public static final String EVENT_TYPE = "playlist_images_generated"; + + public PlaylistImagesGeneratedEvent(@NotNull final PlaylistImagesGeneratedPayload body, + @NotNull final GeneratedPlaylistType type) { + super(body, type); + } + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public PlaylistImagesGeneratedEvent(@JsonProperty("id") @NotNull final String id, + @JsonProperty("creationTime") final long creationTime, + @JsonProperty("body") @NotNull final PlaylistImagesGeneratedPayload body, + @JsonProperty("playlist_type") @NotNull final GeneratedPlaylistType type) { + super(id, creationTime, body, type); + } + + @Override + @NotNull + public String getEventType() { + return EVENT_TYPE; + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistMetaGeneratedEvent.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistMetaGeneratedEvent.java new file mode 100644 index 0000000..e2b142d --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistMetaGeneratedEvent.java @@ -0,0 +1,38 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.GenerativePlaylistEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.PlaylistMetaGeneratedPayload; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.PlaylistTracksGeneratedPayload; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +@EqualsAndHashCode(callSuper = true) +@Value +@JsonIgnoreProperties(ignoreUnknown = true) +public class PlaylistMetaGeneratedEvent extends GenerativePlaylistEvent { + public static final String EVENT_TYPE = "playlist_meta_generated"; + + public PlaylistMetaGeneratedEvent(@NotNull final PlaylistMetaGeneratedPayload body, + @NotNull final GeneratedPlaylistType type) { + super(body, type); + } + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public PlaylistMetaGeneratedEvent(@JsonProperty("id") @NotNull final String id, + @JsonProperty("creationTime") final long creationTime, + @JsonProperty("body") @NotNull final PlaylistMetaGeneratedPayload body, + @JsonProperty("playlist_type") @NotNull final GeneratedPlaylistType type) { + super(id, creationTime, body, type); + } + + @Override + @NotNull + public String getEventType() { + return EVENT_TYPE; + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistTracksGeneratedEvent.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistTracksGeneratedEvent.java new file mode 100644 index 0000000..d4c0946 --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/PlaylistTracksGeneratedEvent.java @@ -0,0 +1,37 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.GenerativePlaylistEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.PlaylistTracksGeneratedPayload; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +@EqualsAndHashCode(callSuper = true) +@Value +@JsonIgnoreProperties(ignoreUnknown = true) +public class PlaylistTracksGeneratedEvent extends GenerativePlaylistEvent { + public static final String EVENT_TYPE = "playlist_tracks_generated"; + + public PlaylistTracksGeneratedEvent(@NotNull final PlaylistTracksGeneratedPayload body, + @NotNull final GeneratedPlaylistType type) { + super(body, type); + } + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public PlaylistTracksGeneratedEvent(@JsonProperty("id") @NotNull final String id, + @JsonProperty("creationTime") final long creationTime, + @JsonProperty("body") @NotNull final PlaylistTracksGeneratedPayload body, + @JsonProperty("playlist_type") final GeneratedPlaylistType type) { + super(id, creationTime, body, type); + } + + @Override + @NotNull + public String getEventType() { + return EVENT_TYPE; + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GeneratedTrack.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GeneratedTrack.java new file mode 100644 index 0000000..7f4f425 --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GeneratedTrack.java @@ -0,0 +1,19 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +@Value +@Builder +@AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) +public class GeneratedTrack { + @NotNull + @JsonProperty("track_id") + String trackId; // track public ID, the same as in Warehouse + @JsonProperty("index") + int index; // index of the track in the playlist +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GenerativePlaylistEvent.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GenerativePlaylistEvent.java new file mode 100644 index 0000000..89e0d03 --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/GenerativePlaylistEvent.java @@ -0,0 +1,47 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.odeyalo.sonata.suite.brokers.events.AbstractEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.GeneratedPlaylistType; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistImagesGeneratedEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistMetaGeneratedEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistTracksGeneratedEvent; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.FieldDefaults; +import org.jetbrains.annotations.NotNull; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.EXISTING_PROPERTY, + property = "event_type" +) +@JsonSubTypes({ + @JsonSubTypes.Type(name = "playlist_tracks_generated", value = PlaylistTracksGeneratedEvent.class), + @JsonSubTypes.Type(name = "playlist_meta_generated", value = PlaylistMetaGeneratedEvent.class), + @JsonSubTypes.Type(name = "playlist_images_generated", value = PlaylistImagesGeneratedEvent.class), +}) +@EqualsAndHashCode(callSuper = true) +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +@Getter +public abstract class GenerativePlaylistEvent extends AbstractEvent { + @JsonProperty("playlist_type") + GeneratedPlaylistType type; + + public GenerativePlaylistEvent(@NotNull final T body, + @NotNull final GeneratedPlaylistType type) { + super(body); + this.type = type; + } + + public GenerativePlaylistEvent(@NotNull final String id, + final long creationTime, + @NotNull final T body, + @NotNull final GeneratedPlaylistType type) { + super(id, creationTime, body); + this.type = type; + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistImagesGeneratedPayload.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistImagesGeneratedPayload.java new file mode 100644 index 0000000..2271ddb --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistImagesGeneratedPayload.java @@ -0,0 +1,44 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistMetaGeneratedEvent; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@Value +@Builder +@AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) +public class PlaylistImagesGeneratedPayload { + @NotNull + @JsonProperty("meta") + PlaylistMetaGeneratedPayload parent; + @JsonProperty("images") + List images; + + @Value + @Builder + @AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) + public static class Image { + @NotNull + @JsonProperty("url") + String url; + @Nullable + @JsonProperty("height") + Integer height; + @Nullable + @JsonProperty("width") + Integer width; + + public Image(@NotNull final String url) { + this.url = url; + this.height = null; + this.width = null; + } + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistMetaGeneratedPayload.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistMetaGeneratedPayload.java new file mode 100644 index 0000000..df64bdc --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistMetaGeneratedPayload.java @@ -0,0 +1,32 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +@Value +@Builder +@AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) +public class PlaylistMetaGeneratedPayload { + @NotNull + @JsonProperty("tracks") + PlaylistTracksGeneratedPayload parent; + @NotNull + @JsonProperty("meta") + Meta meta; + + @Value + @Builder + @AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) + public static class Meta { + @NotNull + @JsonProperty("name") + String name; + @NotNull + @JsonProperty("description") + String description; + } +} diff --git a/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistTracksGeneratedPayload.java b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistTracksGeneratedPayload.java new file mode 100644 index 0000000..4cb4f90 --- /dev/null +++ b/suite-brokers/src/main/java/com/odeyalo/sonata/suite/brokers/events/playlist/gen/payload/PlaylistTracksGeneratedPayload.java @@ -0,0 +1,22 @@ +package com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@Value +@Builder +@AllArgsConstructor(onConstructor_ = {@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)}) +public class PlaylistTracksGeneratedPayload { + @NotNull + @JsonProperty("user_id") + String userId; // a user ID for which this playlist was generated + @NotNull + @JsonProperty("tracks") + List tracks; +} diff --git a/suite-brokers/src/test/java/com/odeyalo/sonata/suite/brokers/GenerativePlaylistEventTest.java b/suite-brokers/src/test/java/com/odeyalo/sonata/suite/brokers/GenerativePlaylistEventTest.java new file mode 100644 index 0000000..a6067d6 --- /dev/null +++ b/suite-brokers/src/test/java/com/odeyalo/sonata/suite/brokers/GenerativePlaylistEventTest.java @@ -0,0 +1,77 @@ +package com.odeyalo.sonata.suite.brokers; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.GeneratedPlaylistType; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistImagesGeneratedEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistMetaGeneratedEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.PlaylistTracksGeneratedEvent; +import com.odeyalo.sonata.suite.brokers.events.playlist.gen.payload.*; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class GenerativePlaylistEventTest { + private final ObjectMapper mapper = new ObjectMapper() + .registerModule(new ParameterNamesModule()); + + @Test + void shouldProperlySerializeDeserializeEvent() throws JsonProcessingException { + final PlaylistTracksGeneratedEvent event = new PlaylistTracksGeneratedEvent( + new PlaylistTracksGeneratedPayload("123", List.of( + new GeneratedTrack("1", 0), + new GeneratedTrack("2", 1), + new GeneratedTrack("3", 2) + )), GeneratedPlaylistType.ON_REPEAT + ); + + final String json = mapper.writeValueAsString(event); + + final GenerativePlaylistEvent actual = mapper.readValue(json, GenerativePlaylistEvent.class); + + assertEquals(event, actual); + } + + @Test + void shouldProperlySerializeDeserializeEvent0() throws JsonProcessingException { + final PlaylistMetaGeneratedEvent event = new PlaylistMetaGeneratedEvent( + new PlaylistMetaGeneratedPayload( + new PlaylistTracksGeneratedPayload("123", List.of( + new GeneratedTrack("1", 0), + new GeneratedTrack("2", 1), + new GeneratedTrack("3", 2) + )), + new PlaylistMetaGeneratedPayload.Meta("On Repeat", "Songs you love the most") + ), GeneratedPlaylistType.ON_REPEAT); + + final String json = mapper.writeValueAsString(event); + + final GenerativePlaylistEvent actual = mapper.readValue(json, GenerativePlaylistEvent.class); + + assertEquals(event, actual); + } + + @Test + void shouldProperlySerializeDeserializeEvent1() throws JsonProcessingException { + final PlaylistImagesGeneratedEvent event = new PlaylistImagesGeneratedEvent( + new PlaylistImagesGeneratedPayload(new PlaylistMetaGeneratedPayload( + new PlaylistTracksGeneratedPayload("123", List.of( + new GeneratedTrack("1", 0), + new GeneratedTrack("2", 1), + new GeneratedTrack("3", 2) + )), + new PlaylistMetaGeneratedPayload.Meta("On Repeat", "Songs you love the most") + ), List.of(new PlaylistImagesGeneratedPayload.Image("cdnimage"))), + GeneratedPlaylistType.ON_REPEAT); + + final String json = mapper.writeValueAsString(event); + + final GenerativePlaylistEvent actual = mapper.readValue(json, GenerativePlaylistEvent.class); + + assertEquals(event, actual); + } +}