Skip to content

Add tests for declarative cache control #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
kotlin-plugin = "2.0.0"
android-plugin = "8.2.2"
apollo = "4.0.0"
apollo = "4.0.1-SNAPSHOT"
okio = "3.9.0"
atomicfu = "0.23.1" # Must be the same version as the one used by apollo-testing-support or native compilation will fail
sqldelight = "2.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.apollographql.cache.normalized.api
import com.apollographql.apollo.api.CompiledField
import com.apollographql.apollo.api.isComposite
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

interface MaxAgeProvider {
/**
Expand Down Expand Up @@ -46,7 +47,7 @@ sealed interface MaxAge {
* Then the lowest of the field's max age and its parent field's max age is returned.
*/
class SchemaCoordinatesMaxAgeProvider(
private val coordinatesToMaxAges: Map<String, MaxAge>,
private val maxAges: Map<String, MaxAge>,
private val defaultMaxAge: Duration,
) : MaxAgeProvider {
override fun getMaxAge(maxAgeContext: MaxAgeContext): Duration {
Expand All @@ -58,7 +59,7 @@ class SchemaCoordinatesMaxAgeProvider(
val fieldName = maxAgeContext.fieldPath.last().name
val fieldParentTypeName = maxAgeContext.fieldPath[maxAgeContext.fieldPath.lastIndex - 1].type.rawType().name
val fieldCoordinates = "$fieldParentTypeName.$fieldName"
val computedFieldMaxAge = when (val fieldMaxAge = coordinatesToMaxAges[fieldCoordinates]) {
val computedFieldMaxAge = when (val fieldMaxAge = maxAges[fieldCoordinates]) {
is MaxAge.Duration -> {
fieldMaxAge.duration
}
Expand All @@ -84,7 +85,7 @@ class SchemaCoordinatesMaxAgeProvider(
private fun getTypeMaxAge(maxAgeContext: MaxAgeContext): Duration {
val field = maxAgeContext.fieldPath.last()
val fieldTypeName = field.type.rawType().name
return when (val typeMaxAge = coordinatesToMaxAges[fieldTypeName]) {
return when (val typeMaxAge = maxAges[fieldTypeName]) {
is MaxAge.Duration -> {
typeMaxAge.duration
}
Expand Down Expand Up @@ -113,3 +114,14 @@ class SchemaCoordinatesMaxAgeProvider(
}
}
}

fun SchemaCoordinatesMaxAgeProvider(maxAges: Map<String, Int>, defaultMaxAge: Duration): MaxAgeProvider {
val mappedMaxAges = maxAges.mapValues {
if (it.value == -1) {
MaxAge.Inherit
} else {
MaxAge.Duration(it.value.seconds)
}
}
return SchemaCoordinatesMaxAgeProvider(mappedMaxAges, defaultMaxAge)
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pluginManagement {
listOf(repositories, dependencyResolutionManagement.repositories).forEach {
it.mavenLocal()
it.mavenCentral()
it.google()
}
Expand Down
10 changes: 8 additions & 2 deletions tests/expiration/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ kotlin {
}

apollo {
service("service") {
packageName.set("sqlite")
service("programmatic") {
packageName.set("programmatic")
srcDir("src/commonMain/graphql/programmatic")
}

service("declarative") {
packageName.set("declarative")
srcDir("src/commonMain/graphql/declarative")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
extend schema @link(
url: "https://specs.apollo.dev/cache/v0.1",
import: ["@cacheControl", "@cacheControlField"]
)

type Query {
user: User
company: Company
products: [Product]
product(id: ID!): Product
node(id: ID!): Node
book: Book
cachedBook: Book @cacheControl(maxAge: 60)
reader: Reader @cacheControl(maxAge: 40)
currentUserId: String
}

type User @cacheControl(maxAge: 10) {
name: String! @cacheControl(maxAge: 5)
email: String! @cacheControl(maxAge: 2)
admin: Boolean
}

type Company {
id: ID!
}

interface Node @cacheControl(maxAge: 30) {
id: ID!
}

type Product implements Node @cacheControl(maxAge: 60) {
id: ID!
name: String!
price: Float!
colors: [ProductColor]
}

union ProductColor = StandardColor | CustomColor

type StandardColor {
color: Color
}

enum Color {
BLACK
WHITE
RED
GREEN
BLUE
ORANGE
}

type CustomColor {
red: Int!
green: Int!
blue: Int!
}


type Book {
title: String
cachedTitle: String @cacheControl(maxAge: 30)
}

type Reader {
book: Book @cacheControl(inheritMaxAge: true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
query GetUser {
user {
name
email
admin
}
}

query GetUserAdmin {
user {
admin
}
}

query GetUserEmail {
user {
email
}
}

query GetUserName {
user {
name
}
}

query GetCompany {
company {
id
}
}

# maxAge: 0
# Query.book doesn't set a maxAge and it's a root field (default 0).
query GetBookTitle {
book { # 0
cachedTitle # 30
}
}

# maxAge: 60
# Query.cachedBook has a maxAge of 60, and Book.title is a scalar, so it
# inherits maxAge from its parent by default.
query GetCachedBookTitle {
cachedBook { # 60
title # inherits
}
}

# maxAge: 30
# Query.cachedBook has a maxAge of 60, but Book.cachedTitle has
# a maxAge of 30.
query GetCachedBookCachedTitle {
cachedBook { # 60
cachedTitle # 30
}
}

# maxAge: 40
# Query.reader has a maxAge of 40. Reader.Book is set to
# inheritMaxAge from its parent, and Book.title is a scalar
# that inherits maxAge from its parent by default.
query GetReaderBookTitle {
reader { # 40
book { # inherits
title # inherits
}
}
}

query GetProducts {
products {
id
name
price
colors {
... on StandardColor {
color
}
... on CustomColor {
red
green
blue
}
}
}
currentUserId
}

query GetProduct {
product(id: "1") {
id
name
price
colors {
... on StandardColor {
color
}
... on CustomColor {
red
green
blue
}
}
}
}

query GetNodes {
node(id: "1") {
id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import com.apollographql.cache.normalized.sql.SqlNormalizedCacheFactory
import com.apollographql.cache.normalized.storeExpirationDate
import com.apollographql.mockserver.MockResponse
import com.apollographql.mockserver.MockServer
import sqlite.GetUserEmailQuery
import sqlite.GetUserNameQuery
import sqlite.GetUserQuery
import programmatic.GetUserEmailQuery
import programmatic.GetUserNameQuery
import programmatic.GetUserQuery
import kotlin.test.Test
import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.seconds
Expand Down
Loading
Loading