Skip to content

Commit 022dad5

Browse files
authored
Extend benefits cookie expiry to 30 days (#7559)
Extend benefits cookie expiry to 30 days. The cookie which tracks when to refresh benefits cookies is reduced to 1 day, like everywhere else. This is part of a wider change to benefits cookie expiration to fix an issue where signed-in users with ad free benefits who didn't visit the site for > the length of the cookie expiration period would sometimes see ads on their first returning pageview. This change makes this less likely to happen by extending the expiration of user benefits cookies. This is due to a race condition between the user benefits refresh and the ads code. However, we don't want to delay ads until after the user benefits have been refreshed as that would impact performance. So instead, extend the expiry of the cookie. See also: guardian/frontend#28352 guardian/dotcom-rendering#14810 guardian/gateway#3285
1 parent abb4820 commit 022dad5

File tree

2 files changed

+35
-28
lines changed

2 files changed

+35
-28
lines changed

support-frontend/app/controllers/SubscriptionProductCookiesCreator.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import com.gu.support.workers._
88

99
case class SubscriptionProductCookiesCreator(domain: GuardianDomain) {
1010
private val oneDayInSeconds = 60 * 60 * 24;
11-
private val maxAgeInDays = 7
11+
private val benefitsCookieLengthInDays = 30
12+
private val benefitsExpiryCookieLengthInDays = 1
1213

13-
private def persistentCookieWithMaxAge(name: String, now: DateTime) = {
14+
private def persistentCookieWithMaxAge(name: String, now: DateTime, maxAgeInDays: Int) = {
1415
val expiryTime = now.plusDays(maxAgeInDays).withTimeAtStartOfDay().getMillis.toString
1516
Cookie(
1617
name = name,
@@ -22,16 +23,20 @@ case class SubscriptionProductCookiesCreator(domain: GuardianDomain) {
2223
)
2324
}
2425
private def adFreeCookie(now: DateTime) =
25-
persistentCookieWithMaxAge("GU_AF1", now)
26+
persistentCookieWithMaxAge(name = "GU_AF1", now = now, maxAgeInDays = benefitsCookieLengthInDays)
2627

2728
private def hideSupportMessagingCookie(now: DateTime) =
28-
persistentCookieWithMaxAge("gu_hide_support_messaging", now)
29+
persistentCookieWithMaxAge(name = "gu_hide_support_messaging", now = now, maxAgeInDays = benefitsCookieLengthInDays)
2930

3031
private def allowRejectAllCookie(now: DateTime) =
31-
persistentCookieWithMaxAge("gu_allow_reject_all", now)
32+
persistentCookieWithMaxAge(name = "gu_allow_reject_all", now = now, maxAgeInDays = benefitsCookieLengthInDays)
3233

3334
private def userBenefitsExpiryCookie(now: DateTime) =
34-
persistentCookieWithMaxAge("gu_user_benefits_expiry", now)
35+
persistentCookieWithMaxAge(
36+
name = "gu_user_benefits_expiry",
37+
now = now,
38+
maxAgeInDays = benefitsExpiryCookieLengthInDays,
39+
)
3540

3641
def createCookiesForProduct(product: ProductType, now: DateTime): List[Cookie] = {
3742
// Setting the user benefits cookies used by frontend. See:

support-frontend/test/controllers/SubscriptionProductCookiesCreatorTest.scala

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,46 @@ class SubscriptionProductCookiesCreatorTest extends AnyFlatSpec with Matchers {
1212
private val now = DateTime.parse("2025-01-01T00:00:00")
1313
private val creator = SubscriptionProductCookiesCreator(GuardianDomain("thegulocal.com"))
1414

15-
private def expectedCookie(name: String) = Cookie(
16-
name = name,
17-
value = "1736294400000", // 2025-01-08T00:00:00 as epoch timestamp,
18-
maxAge = Some(60 * 60 * 24 * 7),
19-
secure = true,
20-
httpOnly = false,
21-
domain = Some("thegulocal.com"),
22-
)
15+
private def expectedCookie(name: String, ageInDays: Int) = {
16+
val ageInSeconds = BigInt(ageInDays * 24 * 60 * 60)
17+
18+
Cookie(
19+
name = name,
20+
value = (now.getMillis + (ageInSeconds * 1000)).toString,
21+
maxAge = Some(ageInSeconds.toInt),
22+
secure = true,
23+
httpOnly = false,
24+
domain = Some("thegulocal.com"),
25+
)
26+
}
2327

2428
"createCookiesForProduct" should "set the gu_allow_reject_all cookie for GuardianAdLite" in {
2529
val guardianAdLite = GuardianAdLite(GBP)
2630
val cookies = creator.createCookiesForProduct(guardianAdLite, now)
2731

28-
cookies should contain(expectedCookie("gu_allow_reject_all"))
29-
cookies should contain(
30-
expectedCookie("gu_user_benefits_expiry"),
31-
) // It should also contain the user features expiry cookie
32+
cookies should contain(expectedCookie(name = "gu_allow_reject_all", ageInDays = 30))
33+
// It should also contain the user features expiry cookie
34+
cookies should contain(expectedCookie(name = "gu_user_benefits_expiry", ageInDays = 1))
3235
}
36+
3337
it should "not set the hide support messaging cookie for Guardian Ad Lite because it is not a supporter product" in {
3438
val guardianAdLite = GuardianAdLite(GBP)
3539
val cookies = creator.createCookiesForProduct(guardianAdLite, now)
3640

37-
cookies should not contain expectedCookie("gu_hide_support_messaging")
38-
cookies should contain(
39-
expectedCookie("gu_user_benefits_expiry"),
40-
) // It should also contain the user features expiry cookie
41+
cookies.map(_.name) should not contain "gu_hide_support_messaging"
42+
// It should also contain the user features expiry cookie
43+
cookies should contain(expectedCookie(name = "gu_user_benefits_expiry", ageInDays = 1))
4144
}
4245

4346
it should "set the ad-free cookie, the hide supporter revenue cookie and the allow reject all cookie for SupporterPlus" in {
4447
val supporterPlus = SupporterPlus(BigDecimal(12), GBP, Monthly)
4548
val cookies = creator.createCookiesForProduct(supporterPlus, now)
4649

47-
cookies should contain(expectedCookie("GU_AF1"))
48-
cookies should contain(expectedCookie("gu_hide_support_messaging"))
49-
cookies should contain(expectedCookie("gu_allow_reject_all"))
50-
cookies should contain(
51-
expectedCookie("gu_user_benefits_expiry"),
52-
) // It should also contain the user features expiry cookie
50+
cookies should contain(expectedCookie(name = "GU_AF1", ageInDays = 30))
51+
cookies should contain(expectedCookie(name = "gu_hide_support_messaging", ageInDays = 30))
52+
cookies should contain(expectedCookie(name = "gu_allow_reject_all", ageInDays = 30))
53+
// It should also contain the user features expiry cookie
54+
cookies should contain(expectedCookie(name = "gu_user_benefits_expiry", ageInDays = 1))
5355
}
5456

5557
}

0 commit comments

Comments
 (0)