Skip to content

Commit

Permalink
Add additional card properties to Feast entities, and amend test
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathonherbert committed Jul 30, 2024
1 parent 19b6f9d commit c8a78f6
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 20 deletions.
26 changes: 21 additions & 5 deletions app/model/FeastAppModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,31 @@ import model.editions.Edition
import play.api.libs.json._

import java.time.LocalDate
import model.editions.Palette

object FeastAppModel {
sealed trait ContainerItem

case class RecipeIdentifier(id:String)
case class Recipe(recipe:RecipeIdentifier) extends ContainerItem
case class Chef(id:String, image:Option[String], bio: Option[String], backgroundHex:Option[String], foregroundHex:Option[String]) extends ContainerItem
case class Palette(backgroundHex:String, foregroundHex:String)
case class FeastCollection(byline:Option[String], darkPalette:Option[Palette], image:Option[String], body:Option[String], title:String, lightPalette:Option[Palette], recipes:Seq[String]) extends ContainerItem
case class RecipeIdentifier(id: String)

case class Recipe(recipe: RecipeIdentifier) extends ContainerItem

case class Chef(id: String,
image: Option[String] = None,
bio: Option[String] = None,
backgroundHex: Option[String] = None,
foregroundHex: Option[String] = None
) extends ContainerItem

case class FeastCollection(
byline: Option[String] = None,
darkPalette: Option[Palette] = None,
image: Option[String] = None,
body: Option[String] = None,
title: String,
lightPalette: Option[Palette] = None,
recipes: Seq[String]
) extends ContainerItem

case class FeastAppContainer(id:String, title:String, body:Option[String], items:Seq[ContainerItem])
//type FeastAppCuration = Map[String, IndexedSeq[FeastAppContainer]]
Expand Down
25 changes: 21 additions & 4 deletions app/services/editions/publishing/FeastPublicationTarget.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import play.api.libs.json.{Json, Writes}
import util.TimestampGenerator

import scala.jdk.CollectionConverters._
import logging.Logging

object FeastPublicationTarget {
object MessageType extends Enumeration {
Expand All @@ -19,8 +20,8 @@ object FeastPublicationTarget {
type MessageType = MessageType.Value
}

class FeastPublicationTarget(snsClient: AmazonSNS, config: ApplicationConfiguration, timestamp: TimestampGenerator) extends PublicationTarget {
private def transformArticles(source: EditionsCard): ContainerItem = {
class FeastPublicationTarget(snsClient: AmazonSNS, config: ApplicationConfiguration, timestamp: TimestampGenerator) extends PublicationTarget with Logging {
private def transformCards(source: EditionsCard): ContainerItem = {
source match {
case _: EditionsArticle => throw new Error("Article not permitted in a Feast Front")
case EditionsRecipe(id, _) => Recipe(RecipeIdentifier(id))
Expand All @@ -29,7 +30,20 @@ class FeastPublicationTarget(snsClient: AmazonSNS, config: ApplicationConfigurat
bio = metadata.flatMap(_.bio),
backgroundHex = metadata.flatMap(_.theme.map(_.palette.backgroundHex)),
foregroundHex = metadata.flatMap(_.theme.map(_.palette.foregroundHex)))
case _:EditionsFeastCollection => FeastCollection(byline=None, darkPalette=None, image=None, body=None, title="", lightPalette=None, recipes=List.empty)
case EditionsFeastCollection(id, addedOn, metadata) =>
val recipes = metadata.map(_.collectionItems.map {
case EditionsRecipe(id, addedOn) => id
}).getOrElse(List.empty)

FeastCollection(
byline = None,
darkPalette = metadata.flatMap(_.theme.map(_.darkPalette)),
lightPalette = metadata.flatMap(_.theme.map(_.lightPalette)),
image = metadata.flatMap(_.theme.flatMap(_.imageURL)),
body = None,
title = metadata.flatMap(_.title).getOrElse("No title"),
recipes = recipes
)
}
}

Expand All @@ -48,7 +62,7 @@ class FeastPublicationTarget(snsClient: AmazonSNS, config: ApplicationConfigurat
id = collection.id,
title = collection.displayName,
body = Some(""), //TBD, this is just how it appears in the data at the moment
items = collection.items.map(transformArticles)
items = collection.items.map(transformCards)
)

def transformContent(source: EditionsIssue, version: String): FeastAppCuration = {
Expand Down Expand Up @@ -80,6 +94,9 @@ class FeastPublicationTarget(snsClient: AmazonSNS, config: ApplicationConfigurat

override def putIssueJson[T: Writes](issue: T, key: String): Unit = {
val content = Json.stringify(Json.toJson(issue))

logger.info(s"Publishing content for issue $key: $content")

snsClient.publish(createPublishRequest(content, FeastPublicationTarget.MessageType.Issue))
}

Expand Down
76 changes: 65 additions & 11 deletions test/services/editions/publishing/FeastPublicationTargetTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@ package services.editions.publishing
import com.amazonaws.services.sns.AmazonSNSClient
import com.amazonaws.services.sns.model.{MessageAttributeValue, PublishRequest, PublishResult}
import conf.ApplicationConfiguration
import model.FeastAppModel
import model.editions.{CuratedPlatform, Edition, EditionsCollection, EditionsFront, EditionsIssue, EditionsRecipe, PublishAction}
import org.mockito.Mockito._
import org.mockito.ArgumentMatchers._
import org.scalatest.{FreeSpec, Matchers}
import org.scalatestplus.mockito.MockitoSugar
import play.api.Configuration
import play.api.libs.json.Json
import model.FeastAppModel.{Chef, FeastAppContainer, Recipe, RecipeIdentifier}
import model.FeastAppModel.{Chef, FeastCollection, FeastAppContainer, Recipe, RecipeIdentifier}
import util.TimestampGenerator

import java.time.LocalDate
import scala.jdk.CollectionConverters._
import scala.util.{Failure, Try}
import model.editions.EditionsFeastCollection
import model.editions.EditionsFeastCollectionMetadata
import model.editions.FeastCollectionTheme
import model.editions.Palette
import model.editions.EditionsChef
import model.editions.EditionsChefMetadata
import model.editions.ChefTheme
import model.editions.Image

class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSugar {
val conf = new ApplicationConfiguration(
Expand Down Expand Up @@ -63,8 +70,40 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
contentPrefillTimeWindow = None,
items=List(
EditionsRecipe(
"id",
"recipe-id",
0L
),
EditionsChef(
"chef-id",
0L,
Some(EditionsChefMetadata(
bio = Some("bio"),
theme = Some(ChefTheme(
id = "theme-id",
palette = Palette("#FFF", "#333"),
)),
chefImageOverride = Some(Image(
width = None,
height = None,
origin = "image-origin",
src = "image-src"
))
))
),
EditionsFeastCollection(
"collection-id",
0L,
Some(EditionsFeastCollectionMetadata(
title = Some("Collection title"),
theme = Some(FeastCollectionTheme(
id = "theme-id",
lightPalette = Palette("#FFF", "#333"),
darkPalette = Palette("#333", "#FFF"),
imageURL = Some("https://example.com/an-image.jpg")
)),
collectionItems = List(EditionsRecipe("nested-recipe-id", 0L))

))
)
)
)
Expand All @@ -82,7 +121,7 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
"recipes" -> FeastAppContainer("recipes", "Recipes", None, Seq(Recipe(RecipeIdentifier("abcdefg"))))
)

"should push the relevant content into SNS" - {
"should push the relevant content into SNS" in {
val mockSNS = mock[AmazonSNSClient]
when(mockSNS.publish(any[PublishRequest])).thenReturn(new PublishResult())

Expand All @@ -101,7 +140,7 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
verify(mockSNS, times(1)).publish(expectedRequest)
}

"should not catch an SNS exception" - {
"should not catch an SNS exception" in {
val mockSNS = mock[AmazonSNSClient]
val except = new RuntimeException("My hovercraft is full of eels")
when(mockSNS.publish(any[PublishRequest])).thenThrow(except)
Expand All @@ -114,7 +153,7 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
}

"putEditionsList" - {
"should push the relevant content into SNS" - {
"should push the relevant content into SNS" in {
val mockSNS = mock[AmazonSNSClient]
when(mockSNS.publish(any[PublishRequest])).thenReturn(new PublishResult())

Expand All @@ -135,7 +174,7 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
}

"transformContent" - {
"should transform the Editions content" - {
"should transform the Editions content" in {
val mockSNS = mock[AmazonSNSClient]
when(mockSNS.publish(any[PublishRequest])).thenReturn(new PublishResult())

Expand All @@ -148,14 +187,29 @@ class FeastPublicationTargetTest extends FreeSpec with Matchers with MockitoSuga
allRecipesFront.head.title shouldBe "Dish of the day"
allRecipesFront.head.body shouldBe Some("") //this is just how the `body` field is currently rendered
allRecipesFront.head.id shouldBe "98e89761-fdf0-4903-b49d-2af7d66fc930"
allRecipesFront.head.items.length shouldBe 1
allRecipesFront.head.items.head.asInstanceOf[FeastAppModel.Recipe].recipe.id shouldBe "id"
allRecipesFront.head.items shouldBe List(
Recipe(RecipeIdentifier("recipe-id")),
Chef(
id = "chef-id",
image = Some("image-src"),
bio = Some("bio"),
backgroundHex = Some("#333"),
foregroundHex = Some("#FFF")
),
FeastCollection(
darkPalette = Some(Palette("#333", "#FFF")),
lightPalette = Some(Palette("#FFF", "#333")),
image = Some("https://example.com/an-image.jpg"),
title = "Collection title",
recipes = List("nested-recipe-id")
)
)
}
}

"putIssue" - {
"should output the transformed version of the content" - {
val serializedVersion = """{"id":"123456ABCD","edition":"feast-northern-hemisphere","issueDate":"2024-05-03","version":"v1","fronts":{"all-recipes":[{"id":"98e89761-fdf0-4903-b49d-2af7d66fc930","title":"Dish of the day","body":"","items":[{"recipe":{"id":"id"}}]}]}}"""
"should output the transformed version of the content" in {
val serializedVersion = """{"id":"123456ABCD","edition":"feast-northern-hemisphere","issueDate":"2024-05-03","version":"v1","fronts":{"all-recipes":[{"id":"98e89761-fdf0-4903-b49d-2af7d66fc930","title":"Dish of the day","body":"","items":[{"recipe":{"id":"recipe-id"}},{"id":"chef-id","image":"image-src","bio":"bio","backgroundHex":"#333","foregroundHex":"#FFF"},{"darkPalette":{"foregroundHex":"#333","backgroundHex":"#FFF"},"image":"https://example.com/an-image.jpg","title":"Collection title","lightPalette":{"foregroundHex":"#FFF","backgroundHex":"#333"},"recipes":["nested-recipe-id"]}]}]}}"""

val mockSNS = mock[AmazonSNSClient]
when(mockSNS.publish(any[PublishRequest])).thenReturn(new PublishResult())
Expand Down

0 comments on commit c8a78f6

Please sign in to comment.