@@ -2,17 +2,75 @@ package com.gu.etagcaching
22
33import com .gu .etagcaching .FreshnessPolicy .TolerateOldValueWhileRefreshing
44import com .gu .etagcaching .Loading .Update
5- import com .gu .etagcaching .fetching .Fetching
6- import org .scalatest .OptionValues
5+ import com .gu .etagcaching .fetching .{ETaggedData , Fetching }
76import org .scalatest .concurrent .{Eventually , ScalaFutures }
87import org .scalatest .flatspec .AnyFlatSpec
98import org .scalatest .matchers .should .Matchers
9+ import org .scalatest .{Inside , OptionValues }
1010
11+ import java .time .DayOfWeek .{SATURDAY , SUNDAY }
12+ import java .time .temporal .ChronoUnit .DAYS
13+ import java .time .{DayOfWeek , ZoneId , ZonedDateTime }
14+ import java .util .Locale
15+ import java .util .Locale .UK
1116import scala .collection .mutable
1217import scala .concurrent .ExecutionContext .Implicits .global
1318import scala .concurrent .duration ._
1419
15- class LoadingTest extends AnyFlatSpec with Matchers with ScalaFutures with OptionValues with Eventually {
20+ class LoadingTest extends AnyFlatSpec with Matchers with ScalaFutures with OptionValues with Eventually with Inside {
21+ val exampleFetchingDayLength : Fetching [ZonedDateTime , java.time.Duration ] = TestFetching .withLookup { dateTime =>
22+ val day = dateTime.truncatedTo(DAYS )
23+ Some (java.time.Duration .between(day, day.plusDays(1 )))
24+ }
25+ val momentInShortUKDay : ZonedDateTime = ZonedDateTime .of(2025 , 3 , 30 , 21 , 55 , 56 , 0 , ZoneId .of(" Europe/London" ))
26+ val momentInNormalUSDay : ZonedDateTime = momentInShortUKDay.withZoneSameInstant(ZoneId .of(" America/Chicago" ))
27+
28+ " Creating a Loading instance from a Fetching instance" should " work with 'thenParsing'" in {
29+ val loading : Loading [ZonedDateTime , Long ] = exampleFetchingDayLength.thenParsing(_.toHours)
30+
31+ loading.fetchAndParse(momentInShortUKDay).futureValue.toOption.value shouldBe 23
32+ }
33+
34+ it should " work with 'thenParsingWithKey'" in {
35+ val loading : Loading [ZonedDateTime , String ] =
36+ exampleFetchingDayLength.thenParsingWithKey((key, response) => s " ${key.getZone.getId.split('/' )(1 )}: ${response.toHours} hours " )
37+
38+ loading.fetchAndParse(momentInShortUKDay).futureValue.toOption.value shouldBe " London: 23 hours"
39+ loading.fetchAndParse(momentInNormalUSDay).futureValue.toOption.value shouldBe " Chicago: 24 hours"
40+ }
41+
42+ private def loadingFavouriteDayOfWeekInDifferentCountries () = new TestLoading [Locale , String , DayOfWeek ](DayOfWeek .valueOf)
43+
44+ " Loading" should " not do any parsing if fetching found no change" in {
45+ val sample = loadingFavouriteDayOfWeekInDifferentCountries()
46+
47+ sample.dataStore(UK ) = " SATURDAY"
48+ inside(sample.loading.fetchAndParse(UK ).futureValue) {
49+ case initialLoad : ETaggedData [DayOfWeek ] =>
50+ sample.countingParser.count() shouldBe 1
51+ initialLoad.result shouldBe SATURDAY
52+
53+ sample.loading.fetchThenParseIfNecessary(UK , initialLoad).futureValue.toOption.value shouldBe SATURDAY
54+ sample.countingParser.count() shouldBe 1
55+ }
56+ }
57+
58+ it should " do parsing when values change" in {
59+ val sample = loadingFavouriteDayOfWeekInDifferentCountries()
60+
61+ sample.dataStore(UK ) = " SATURDAY"
62+ inside(sample.loading.fetchAndParse(UK ).futureValue) {
63+ case initialLoad : ETaggedData [DayOfWeek ] =>
64+ sample.countingParser.count() shouldBe 1
65+ initialLoad.result shouldBe SATURDAY
66+
67+ sample.dataStore(UK ) = " SUNDAY"
68+ sample.loading.fetchThenParseIfNecessary(UK , initialLoad).futureValue.toOption.value shouldBe SUNDAY
69+ sample.countingParser.count() shouldBe 2
70+ }
71+ }
72+
73+
1674 " onUpdate" should " give callbacks that allow logging updates" in {
1775 val updates : mutable.Buffer [Update [String , Int ]] = mutable.Buffer .empty
1876
@@ -43,3 +101,9 @@ class LoadingTest extends AnyFlatSpec with Matchers with ScalaFutures with Optio
43101 updates.toSeq shouldBe expectedUpdates // No updates if we're not requesting the key from the cache
44102 }
45103}
104+
105+ class TestLoading [K , Response , V ](parser : Response => V ) {
106+ val dataStore = mutable.Map [K , Response ]()
107+ val countingParser = new CountingParser [Response , V ](parser)
108+ val loading : Loading [K , V ] = TestFetching .withLookup(dataStore.get).thenParsing(countingParser)
109+ }
0 commit comments