Skip to content

Commit aa5cc4e

Browse files
committed
clean up
1 parent ba7f7fb commit aa5cc4e

9 files changed

Lines changed: 116 additions & 645 deletions

File tree

api-models/src/main/scala/com/gu/mobile.notifications.client/models/Payloads.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ object FootballPenaltyShootoutPayload {
236236
"type" -> FootballPenaltyShootout.toString,
237237
"title" -> o.title,
238238
"message" -> o.message,
239+
"thumbnailUrl" -> o.thumbnailUrl,
239240
"sender" -> o.sender,
240241
"awayTeamName" -> o.awayTeamName,
241242
"awayTeamScore" -> o.awayTeamScore,
@@ -260,13 +261,15 @@ object FootballPenaltyShootoutPayload {
260261
"matchStatus" -> o.matchStatus,
261262
"eventId" -> o.eventId,
262263
"kickOffTimestamp" -> o.kickOffTimestamp,
264+
"lineupsAvailable" -> o.lineupsAvailable,
263265
"detailedMatchStatus" -> o.detailedMatchStatus,
264266
"debug" -> o.debug
265267
)
266268
}
267269
case class FootballPenaltyShootoutPayload(
268270
title: Option[String],
269271
message: Option[String],
272+
thumbnailUrl: Option[URI] = None,
270273
sender: String,
271274
awayTeamName: String,
272275
awayTeamScore: Int,
@@ -291,6 +294,7 @@ case class FootballPenaltyShootoutPayload(
291294
matchStatus: String,
292295
eventId: String,
293296
kickOffTimestamp: Option[Long] = None,
297+
lineupsAvailable: Option[Boolean] = None,
294298
detailedMatchStatus: Option[String] = None,
295299
debug: Boolean,
296300
dryRun: Option[Boolean]

common/src/main/scala/models/Notification.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ case class FootballPenaltyShootoutNotification(
176176
`type`: NotificationType = NotificationType.FootballPenaltyShootout,
177177
title: Option[String],
178178
message: Option[String],
179+
thumbnailUrl: Option[URI] = None,
179180
sender: String,
180181
awayTeamName: String,
181182
awayTeamScore: Int,
@@ -200,6 +201,7 @@ case class FootballPenaltyShootoutNotification(
200201
matchStatus: String,
201202
eventId: String,
202203
kickOffTimestamp: Option[Long] = None,
204+
lineupsAvailable: Option[Boolean] = None,
203205
detailedMatchStatus: Option[String] = None,
204206
debug: Boolean,
205207
dryRun: Option[Boolean]

football/src/main/scala/com/gu/mobile/notifications/football/lib/EventConsumer.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ class EventConsumer(
2828
val liveActivityEventTypes =
2929
List(
3030

31-
// penalty shootout events
32-
// "shootoutGoal",
33-
// "shootoutMiss",
34-
// "shootoutSave",
3531
// additional synthetic live activity life cycle events
3632
"create-channel",
3733
"start-live-activity",

football/src/main/scala/com/gu/mobile/notifications/football/notificationbuilders/MatchStatusNotificationBuilder.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import java.net.URI
44
import java.util.UUID
55
import com.gu.mobile.notifications.client.models.Importance.{Importance, Major, Minor}
66
import com.gu.mobile.notifications.client.models._
7-
import com.gu.mobile.notifications.client.models.liveActitivites.MatchStatus
87
import com.gu.mobile.notifications.football.models.{Dismissal, FootballMatchEvent, FullTime, Goal, HalfTime, KickOff, PenaltyShootoutKick, PenaltyShootoutScore, RedCards, Score, SecondHalf}
98
import pa.{MatchDay, MatchDayTeam}
109

@@ -17,7 +16,7 @@ class MatchStatusNotificationBuilder(mapiHost: String) {
1716
matchInfo: MatchDay,
1817
previousEvents: List[FootballMatchEvent],
1918
articleId: Option[String]
20-
): NotificationPayload = {
19+
): FootballMatchStatusPayload = {
2120
val liveActivityTopics =
2221
if (triggeringEvent.isInstanceOf[KickOff])
2322
List(
@@ -26,7 +25,7 @@ class MatchStatusNotificationBuilder(mapiHost: String) {
2625
Topic(TopicTypes.FootballMatchLiveActivity, matchInfo.id)
2726
)
2827
else Nil
29-
28+
3029
val topics = List(
3130
Topic(TopicTypes.FootballTeam, matchInfo.homeTeam.id),
3231
Topic(TopicTypes.FootballTeam, matchInfo.awayTeam.id),
@@ -72,6 +71,7 @@ class MatchStatusNotificationBuilder(mapiHost: String) {
7271
matchStatus = status,
7372
eventId = UUID.nameUUIDFromBytes(triggeringEvent.eventId.getBytes).toString,
7473
kickOffTimestamp = Some(matchInfo.date.toEpochSecond),
74+
lineupsAvailable = Some(matchInfo.lineupsAvailable),
7575
detailedMatchStatus = Some("PENALTIES"),
7676
debug = false,
7777
dryRun = None

football/src/test/scala/com/gu/mobile/notifications/football/lib/EventConsumerSpec.scala

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,29 @@ class EventConsumerSpec(implicit ev: ExecutionEnv)
352352
result must not contain((payload: NotificationPayload) => payload.title.getOrElse("") == "Penalty Kick")
353353
}
354354

355+
"generate FootballPenaltyShootoutPayload for shootout events" in new MatchEventsContext {
356+
override def matchDayLA: MatchDay =
357+
super.matchDayLA.copy(date = ZonedDateTime.now().plusHours(1))
358+
359+
val result: List[NotificationPayload] =
360+
eventConsumer.eventsToNotifications(matchDataLA)
361+
362+
result must contain(beAnInstanceOf[FootballPenaltyShootoutPayload])
363+
}
364+
}
365+
366+
"NOT generate notification payload for extra time match phase events" in new MatchEventsContext {
367+
override def matchDayLA: MatchDay =
368+
super.matchDayLA.copy(date = ZonedDateTime.now(), matchStatus = "ETS")
369+
370+
val result: List[NotificationPayload] =
371+
eventConsumer.eventsToNotifications(matchDataLA)
372+
373+
result must forall((payload: NotificationPayload) =>
374+
payload.title.getOrElse("") != "The Guardian"
375+
) // default string for unknown events
376+
}
377+
355378
}
356379

357380
"A LiveActivity EventConsumer handles synthetic events and" should {
@@ -663,19 +686,4 @@ class EventConsumerSpec(implicit ev: ExecutionEnv)
663686
)
664687
)
665688
}
666-
667-
trait WorldCupContext extends Scope {
668-
val matchStatusNotificationBuilder = new MatchStatusNotificationBuilder("https://mobile.guardianapis.com")
669-
val eventConsumer = new EventConsumer(matchStatusNotificationBuilder)
670-
671-
def loadFile(file: String): String = {
672-
val stream = this.getClass.getClassLoader.getResourceAsStream(file)
673-
Source.fromInputStream(stream).mkString
674-
}
675-
676-
def rawEvents: List[MatchEvent] = Parser.parseMatchEvents(loadFile("worldcup/match-event-feed.xml")).get.events
677-
def matchDay: MatchDay = Parser.parseMatchDay(loadFile("worldcup/match-day.xml")).head
678-
def matchEvents: List[MatchEvent] = new SyntheticMatchEventGenerator(() => ZonedDateTime.now()).generate(rawEvents, "4356015", matchDay)
679-
def matchData = MatchDataWithArticle(matchDay, matchEvents, None)
680-
}
681689
}

football/src/test/scala/com/gu/mobile/notifications/football/notificationbuilders/MatchStatusNotificationBuilderSpec.scala

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,25 @@ class MatchStatusNotificationBuilderSpec extends Specification {
9595
val notification = builder.build(secondDismissal, matchInfo, List(firstDismissal), None).asInstanceOf[FootballMatchStatusPayload]
9696
notification.homeTeamRedCards shouldEqual 2
9797
notification.awayTeamRedCards shouldEqual 0
98-
notification must not(beAnInstanceOf[FootballPenaltyShootoutPayload])
9998
}
10099

101-
102100
"Return FootballPenaltyShootoutPayload for a penalty shootout kick" in new MatchEventsContext {
103101
val shootoutKick = PenaltyShootoutKick(ScoredShootoutResult, "Player", home, away, 1, "event-1")
104102
val notification = builder.build(shootoutKick, matchInfo.copy(matchStatus = "PT"), List.empty, None)
105103
notification must beAnInstanceOf[FootballPenaltyShootoutPayload]
106-
}
107-
108-
"Not return FootballMatchStatusPayload for a penalty shootout kick" in new MatchEventsContext {
109-
val shootoutKick = PenaltyShootoutKick(ScoredShootoutResult, "Player", home, away, 1, "event-1")
110-
val notification = builder.build(shootoutKick, matchInfo.copy(matchStatus = "PT"), List.empty, None)
111104
notification must not(beAnInstanceOf[FootballMatchStatusPayload])
112105
}
113106

114107
"Not return FootballPenaltyShootoutPayload for a goal" in new MatchEventsContext {
115108
val notification = builder.build(baseGoal, matchInfo, List.empty, None)
116109
notification must not(beAnInstanceOf[FootballPenaltyShootoutPayload])
117110
}
111+
112+
"Not return FootballPenaltyShootoutPayload for dismissal" in new MatchEventsContext {
113+
val dismissal = Dismissal("e2", "Player B", home, 80, None)
114+
val notification = builder.build(baseGoal, matchInfo, List(dismissal), None)
115+
notification must not(beAnInstanceOf[FootballPenaltyShootoutPayload])
116+
}
118117
}
119118

120119
trait MatchEventsContext extends Scope {
@@ -145,21 +144,4 @@ class MatchStatusNotificationBuilderSpec extends Specification {
145144
comments = None
146145
)
147146
}
148-
149-
trait WorldCupContext extends Scope {
150-
val builder = new MatchStatusNotificationBuilder("http://localhost")
151-
152-
def loadFile(file: String): String = {
153-
val stream = this.getClass.getClassLoader.getResourceAsStream(file)
154-
Source.fromInputStream(stream).mkString
155-
}
156-
157-
def matchInfo: MatchDay = Parser.parseMatchDay(loadFile("worldcup/match-day.xml")).head
158-
def rawEvents = Parser.parseMatchEvents(loadFile("worldcup/match-event-feed.xml")).get.events
159-
def allEvents: List[FootballMatchEvent] =
160-
new SyntheticMatchEventGenerator(() => ZonedDateTime.now())
161-
.generate(rawEvents, matchInfo.id, matchInfo)
162-
.flatMap(FootballMatchEvent.fromPaMatchEvent(matchInfo.homeTeam, matchInfo.awayTeam)(_))
163-
def dismissals = allEvents.collect { case d: Dismissal => d }
164-
}
165147
}

notificationworkerlambda/src/main/scala/com/gu/notifications/worker/delivery/fcm/models/payload/FcmPayloadBuilder.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,15 @@ object FcmPayloadBuilder {
150150
Keys.Importance -> n.importance.toString,
151151
Keys.MatchStatus -> n.matchStatus,
152152
Keys.MatchId -> n.matchId,
153-
Keys.MatchInfoUri -> n.matchInfoUri.toString,
154-
Keys.HomeTeamRedCards -> n.homeTeamRedCards.toString,
155-
Keys.AwayTeamRedCards -> n.awayTeamRedCards.toString
153+
Keys.MatchInfoUri -> n.matchInfoUri.toString
156154
) ++ n.articleUri.map(Keys.ArticleUri -> _.toString).toMap
157155
++ n.competitionName.map(Keys.CompetitionName -> _).toMap
158156
++ n.venue.map(Keys.Venue -> _).toMap
159157
++ n.roundName.map(Keys.RoundName -> _).toMap
158+
++ Some(Keys.HomeTeamRedCards -> n.homeTeamRedCards.toString).toMap
159+
++ Some(Keys.AwayTeamRedCards -> n.awayTeamRedCards.toString).toMap
160160
++ n.detailedMatchStatus.map(Keys.DetailedMatchStatus -> _).toMap
161+
++ n.lineupsAvailable.map(v => Keys.LineupsAvailable -> v.toString).toMap
161162
++ n.kickOffTimestamp.map(Keys.KickOffTimestamp -> _.toString).toMap
162163
++ n.homeTeamPenalties.map(p => Map(
163164
Keys.HomeTeamPenaltiesScored -> p.scored.toString,

notificationworkerlambda/src/test/scala/com/gu/notifications/worker/delivery/fcm/models/payload/FcmPayloadBuilderSpec.scala

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class FcmPayloadBuilderSpec extends Specification with Matchers {
3737
"generate correct data for US Elections notification" in new UsElectionNotificationScope {
3838
check()
3939
}
40+
"generate correct data for Penalty Shootout notification" in new PenaltyShootoutNotificationScope {
41+
check()
42+
}
4043
}
4144

4245
trait NotificationScope extends Scope {
@@ -335,6 +338,77 @@ class FcmPayloadBuilderSpec extends Specification with Matchers {
335338
))
336339
}
337340

341+
trait PenaltyShootoutNotificationScope extends NotificationScope {
342+
val notification = models.FootballPenaltyShootoutNotification(
343+
id = UUID.fromString("4c261110-4672-4451-a5b8-3422c6839c42"),
344+
title = Some("Penalty Kick"),
345+
message = Some("Netherlands 2-2 Argentina (PT)"),
346+
sender = "UnitTests",
347+
importance = Major,
348+
topic = List(Topic(`type` = Breaking, name = "uk")),
349+
awayTeamName = "Argentina",
350+
awayTeamScore = 2,
351+
awayTeamMessage = "Messi 73'",
352+
awayTeamId = "965",
353+
awayTeamRedCards = 0,
354+
awayTeamPenalties = Some(models.PenaltyScore(scored = 2, missed = 0, saved = 1)),
355+
homeTeamName = "Netherlands",
356+
homeTeamScore = 2,
357+
homeTeamMessage = "Weghorst 83'",
358+
homeTeamId = "631",
359+
homeTeamRedCards = 1,
360+
homeTeamPenalties = Some(models.PenaltyScore(scored = 3, missed = 1, saved = 0)),
361+
competitionName = Some("World Cup"),
362+
venue = Some("Lusail"),
363+
matchId = "4356015",
364+
matchInfoUri = new URI("https://some.invalid.url/detail"),
365+
articleUri = Some(new URI("https://some.other.invalid.url/detail")),
366+
matchStatus = "PT",
367+
eventId = "2",
368+
kickOffTimestamp = Some(1746619200L),
369+
lineupsAvailable = Some(true),
370+
detailedMatchStatus = Some("PENALTIES"),
371+
debug = true,
372+
dryRun = None
373+
)
374+
375+
val expected = Some(
376+
FirebaseAndroidNotification(
377+
notificationId = UUID.fromString("4c261110-4672-4451-a5b8-3422c6839c42"),
378+
data = Map(
379+
Keys.Type -> MessageTypes.FootballPenaltyShootout,
380+
"homeTeamName" -> "Netherlands",
381+
"homeTeamId" -> "631",
382+
"homeTeamScore" -> "2",
383+
"homeTeamText" -> "Weghorst 83'",
384+
"awayTeamName" -> "Argentina",
385+
"awayTeamId" -> "965",
386+
"awayTeamScore" -> "2",
387+
"awayTeamText" -> "Messi 73'",
388+
"importance" -> "Major",
389+
"matchStatus" -> "PT",
390+
"matchId" -> "4356015",
391+
"matchInfoUri" -> "https://some.invalid.url/detail",
392+
"articleUri" -> "https://some.other.invalid.url/detail",
393+
"competitionName" -> "World Cup",
394+
"venue" -> "Lusail",
395+
"homeTeamRedCards" -> "1",
396+
"awayTeamRedCards" -> "0",
397+
Keys.KickOffTimestamp -> "1746619200",
398+
Keys.LineupsAvailable -> "true",
399+
Keys.DetailedMatchStatus -> "PENALTIES",
400+
Keys.HomeTeamPenaltiesScored -> "3",
401+
Keys.HomeTeamPenaltiesMissed -> "1",
402+
Keys.HomeTeamPenaltiesSaved -> "0",
403+
Keys.AwayTeamPenaltiesScored -> "2",
404+
Keys.AwayTeamPenaltiesMissed -> "0",
405+
Keys.AwayTeamPenaltiesSaved -> "1"
406+
),
407+
ttl = TimeToLive.FootballMatchStatusTtl
408+
)
409+
)
410+
}
411+
338412
trait UsElectionNotificationScope extends NotificationScope {
339413
val notification = models.Us2020ResultsNotification(
340414
id = UUID.fromString("3e0bc788-a27c-4864-bb71-77a80aadcce4"),

0 commit comments

Comments
 (0)