Skip to content

Commit d0acd75

Browse files
authored
Merge pull request #358 from guardian/ab/main-media-bug
Main media selection bug
2 parents dbf4b3c + a940935 commit d0acd75

3 files changed

Lines changed: 26 additions & 10 deletions

File tree

build.sbt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ def fapiClient(playJsonVersion: PlayJsonVersion) = playJsonSpecificProject("fap
8282
contentApiDefault,
8383
commercialShared,
8484
scalaTestMockito,
85-
mockito
85+
mockito,
86+
jSoup
8687
),
8788
artifactProducingSettings(supportScala3 = false) // currently blocked by contentApi & commercialShared clients
8889
)

fapi-client/src/main/scala/com/gu/facia/api/models/collection.scala

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package com.gu.facia.api.models
22

33
import com.gu.contentapi.client.ContentApiClient
4-
import com.gu.contentapi.client.model.v1.{Content, ItemResponse}
4+
import com.gu.contentapi.client.model.v1.Content
55
import com.gu.contentatom.thrift.{Atom, AtomData}
66
import com.gu.contentatom.thrift.atom.media.MediaAtom
7-
import com.gu.facia.api.contentapi.{ LatestSnapsRequest, LinkSnapsRequest}
7+
import com.gu.facia.api.contentapi.{LatestSnapsRequest, LinkSnapsRequest}
88
import com.gu.facia.client.models.{CollectionJson, SupportingItem, TargetedTerritory, Trail}
99
import org.joda.time.{DateTime, DateTimeZone}
1010
import com.gu.facia.api.utils.BoostLevel
11-
import com.gu.facia.api.{CapiError, Response}
11+
import com.gu.facia.api.Response
1212
import com.typesafe.scalalogging.StrictLogging
13+
import org.jsoup.Jsoup
1314

1415
import scala.concurrent.{ExecutionContext, Future}
1516

16-
1717
case class Collection(
1818
id: String,
1919
displayName: String,
@@ -131,7 +131,7 @@ object Collection extends StrictLogging {
131131
case faciaContent@AtomId(atomId) if faciaContent.properties.videoReplace =>
132132
capiClient.getResponse(ContentApiClient.item(atomId)).map { response =>
133133
response.media.flatMap(atom =>
134-
Option.when(isValidMediaAtom(atom, atomId))(atom)
134+
Option.when(isValidMediaAtom(atom))(atom)
135135
)
136136
}.recover {
137137
case e =>
@@ -140,10 +140,12 @@ object Collection extends StrictLogging {
140140
}
141141

142142
case faciaContent: CuratedContent if faciaContent.properties.showMainVideo =>
143+
val mainField = faciaContent.content.fields.flatMap(_.main).get
143144
val mainAtom = for {
145+
atomId <- extractMainMediaAtomIdFromHtml(mainField)
144146
atoms <- faciaContent.content.atoms
145147
mediaAtoms <- atoms.media
146-
validMediaAtom <- mediaAtoms.find(isValidMediaAtom(_, faciaContent.content.id))
148+
validMediaAtom <- mediaAtoms.find(atom => atom.id == atomId && isValidMediaAtom(atom))
147149
} yield validMediaAtom
148150
Future.successful(mainAtom)
149151
case _ => Future.successful(None)
@@ -152,17 +154,29 @@ object Collection extends StrictLogging {
152154
Response.Async.Right(futureMaybeAtomData)
153155
}
154156

155-
def isValidMediaAtom(atom: Atom, id: String): Boolean = {
157+
//
158+
// We need to make sure that we only select the main media atom rather than another embedded atom. This follows the same pattern implemented in Frontend.
159+
//
160+
def extractMainMediaAtomIdFromHtml(html: String): Option[String] = {
161+
for {
162+
document <- Some(Jsoup.parse(html))
163+
atomContainer <- Option(document.getElementsByClass("element-atom").first())
164+
bodyElement <- Some(atomContainer.getElementsByTag("gu-atom"))
165+
atomId <- Some(bodyElement.attr("data-atom-id"))
166+
} yield atomId
167+
}
168+
169+
def isValidMediaAtom(atom: Atom): Boolean = {
156170
atom.data match {
157171
case mediaData: AtomData.Media =>
158172
if (!isExpired(mediaData.media)) {
159173
true
160174
} else {
161-
logger.warn(s"Media atom is expired in ${id}")
175+
logger.warn(s"Media atom ${atom.id} is expired")
162176
false
163177
}
164178
case _ =>
165-
logger.warn(s"No valid media atom found in ${id}")
179+
logger.warn(s"Media atom ${atom.id} is not valid")
166180
false
167181
}
168182
}

project/dependencies.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ object Dependencies {
1515
val scalaTest = "org.scalatest" %% "scalatest" % "3.2.18" % Test
1616
val scalaLogging = "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5"
1717
val commercialShared = "com.gu" %% "commercial-shared" % "6.1.8"
18+
val jSoup = "org.jsoup" % "jsoup" % "1.21.1"
1819

1920
case class PlayJsonVersion(
2021
majorMinorVersion: String,

0 commit comments

Comments
 (0)