Skip to content

Commit

Permalink
Make overquota cost only apply to images that would otherwise be free
Browse files Browse the repository at this point in the history
ie. excluded supplierCollections still appear as cost=pay, even if the
agency is otherwise overquota
  • Loading branch information
andrew-nowak committed Feb 19, 2025
1 parent 70604db commit 3d3882a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 26 deletions.
48 changes: 25 additions & 23 deletions media-api/app/lib/usagerights/CostCalculator.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package lib.usagerights

import com.gu.mediaservice.lib.config.RuntimeUsageRightsConfig
import com.gu.mediaservice.model._
import lib.UsageQuota

trait CostCalculator {
val defaultCost = Pay
val defaultCost: Cost = Pay
val freeSuppliers: List[String]
val suppliersCollectionExcl: Map[String, List[String]]
val quotas: UsageQuota

def getCost(supplier: String, collection: Option[String]): Option[Cost] = {
val free = isFreeSupplier(supplier) && ! collection.exists(isExcludedColl(supplier, _))
if (free) Some(Free) else None
private def getAgencyCost(agencyUsageRights: Agency): Option[Cost] = {
val supplier = agencyUsageRights.supplier
val isFreeFromAgency = isFreeSupplier(supplier) && !agencyUsageRights.suppliersCollection.exists(isExcludedColl(supplier, _))

if (isFreeFromAgency) {
if (isOverQuota(agencyUsageRights)) {
Some(Overquota)
} else {
Some(Free)
}
} else {
None
}
}

def isConditional(usageRights: UsageRights): Boolean =
Expand All @@ -21,27 +30,20 @@ trait CostCalculator {
def isPay(usageRights: UsageRights): Boolean =
getCost(usageRights) == Pay

def getOverQuota(usageRights: UsageRights) =
if (quotas.isOverQuota(usageRights)) {
Some(Overquota)
} else {
None
}
def isOverQuota(usageRights: UsageRights): Boolean = quotas.isOverQuota(usageRights)

def getCost(usageRights: UsageRights): Cost = {
val restricted : Option[Cost] = usageRights.restrictions.map(r => Conditional)
val categoryCost: Option[Cost] = usageRights.defaultCost
val overQuota: Option[Cost] = getOverQuota(usageRights)
val supplierCost: Option[Cost] = usageRights match {
case u: Agency => getCost(u.supplier, u.suppliersCollection)
case _ => None
}
val restricted: Option[Cost] = usageRights.restrictions.map(r => Conditional)
val categoryCost: Option[Cost] = usageRights.defaultCost
val supplierCost: Option[Cost] = usageRights match {
case u: Agency => getAgencyCost(u)
case _ => None
}

restricted
.orElse(overQuota)
.orElse(categoryCost)
.orElse(supplierCost)
.getOrElse(defaultCost)
restricted
.orElse(categoryCost)
.orElse(supplierCost)
.getOrElse(defaultCost)
}

private def isFreeSupplier(supplier: String) = freeSuppliers.contains(supplier)
Expand Down
3 changes: 2 additions & 1 deletion media-api/test/scala/lib/ImageExtrasTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class ImageExtrasTest extends AnyFunSpec with Matchers with MockitoSugar {

object Costing extends CostCalculator {
val quotas: UsageQuota = Quota
override def getOverQuota(usageRights: UsageRights): Option[Nothing] = None

override def isOverQuota(usageRights: UsageRights): Boolean = false
override val freeSuppliers: List[String] = GuardianUsageRightsConfig.freeSuppliers
override val suppliersCollectionExcl: Map[String, List[String]] = GuardianUsageRightsConfig.suppliersCollectionExcl
}
Expand Down
11 changes: 9 additions & 2 deletions media-api/test/usagerights/CostCalculatorTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ class CostCalculatorTest extends AnyFunSpec with Matchers with MockitoSugar {

object Costing extends CostCalculator {
val quotas = Quota
override def getOverQuota(usageRights: UsageRights) = None
override def isOverQuota(usageRights: UsageRights) = false

override val freeSuppliers: List[String] = GuardianUsageRightsConfig.freeSuppliers
override val suppliersCollectionExcl: Map[String, List[String]] = GuardianUsageRightsConfig.suppliersCollectionExcl
}

object OverQuotaCosting extends CostCalculator {
val quotas = Quota
override def getOverQuota(usageRights: UsageRights) = Some(Overquota)
override def isOverQuota(usageRights: UsageRights) = true

override val freeSuppliers: List[String] = GuardianUsageRightsConfig.freeSuppliers
override val suppliersCollectionExcl: Map[String, List[String]] = GuardianUsageRightsConfig.suppliersCollectionExcl
Expand Down Expand Up @@ -65,5 +65,12 @@ class CostCalculatorTest extends AnyFunSpec with Matchers with MockitoSugar {

cost should be (Pay)
}

it("Pay should trump Overquota with a free supplier whose gone over quota, but excluded collection") {
val usageRights = Agency("Getty Images", Some("Bob Thomas Sports Photography"))
val cost = OverQuotaCosting.getCost(usageRights)

cost should be (Pay)
}
}
}

0 comments on commit 3d3882a

Please sign in to comment.