tests/testthat/test-cache.R

context("Caching")

test_that("Cache is on by default", {
    expect_true(is.null(getOption("httpcache.on")))
    expect_true(caching())
})
test_that("httpcache.on option affects caching", {
    on.exit(options(httpcache.on=NULL))
    options(httpcache.on=FALSE)
    expect_false(caching())
    options(httpcache.on=TRUE)
    expect_true(caching())
})

public({
    clearCache()

    test_that("Cache gets set on GET", {
        expect_length(cacheKeys(), 0)
        with_fake_http({
            expect_GET(a <- GET("https://app.crunch.io/api/datasets"),
                "https://app.crunch.io/api/datasets")
            expect_GET(b <- GET("https://app.crunch.io/api/", query=list(user="me")),
                "https://app.crunch.io/api/?user=me")
        })
        expect_length(cacheKeys(), 2)
        expect_true(hitCache("https://app.crunch.io/api/datasets"))
        expect_identical(a, getCache("https://app.crunch.io/api/datasets"))
    })

    without_internet({
        test_that("When the cache is set, can read from it even with no connection", {
            ## Now read from cache
            expect_identical(GET("https://app.crunch.io/api/datasets")$url,
                "https://app.crunch.io/api/datasets")
        })
        test_that("But uncached() prevents reading from the cache", {
            expect_error(uncached(GET("https://app.crunch.io/api/datasets")),
                "GET https://app.crunch.io/api/datasets")
        })
    })

    test_that("PUT busts cache", {
        ## Now bust cache
        with_fake_http({
            expect_PUT(PUT("https://app.crunch.io/api/datasets"),
                "https://app.crunch.io/api/datasets")
        })
        ## See that it's no longer in the cache
        expect_length(cacheKeys(), 1)
        without_internet({
            expect_error(GET("https://app.crunch.io/api/datasets"),
                "GET https://app.crunch.io/api/datasets")
        })
    })

    test_that("PATCH busts cache", {
        without_internet({
            ## It's in the cache
            expect_no_request(q <- GET("https://app.crunch.io/api/",
                query=list(user="me")))
            expect_identical(q$url, "https://app.crunch.io/api/?user=me")
            ## Hey, let's try with the cache API
            expect_identical(getCache(buildCacheKey("https://app.crunch.io/api/",
                query=list(user="me"))), q)
        })
        ## Now bust cache
        with_fake_http({
            expect_PATCH(PATCH("https://app.crunch.io/api/"),
                "https://app.crunch.io/api/")
        })
        ## See that it's no longer in the cache
        expect_length(cacheKeys(), 0)
        without_internet({
            expect_GET(GET("https://app.crunch.io/api/", query=list(user="me")),
                "https://app.crunch.io/api/?user=me")
        })
    })

    test_that("POST busts cache more narrowly by default: setup", {
        with_fake_http({
            expect_GET(a <<- GET("https://app.crunch.io/api/datasets"),
                "https://app.crunch.io/api/datasets")
            expect_GET(b <<- GET("https://app.crunch.io/api/", query=list(user="me")),
                "https://app.crunch.io/api/?user=me")
        })
    })
    without_internet({
        test_that("See that cache is set", {
            ## Now read from cache
            expect_no_request(
                expect_identical(GET("https://app.crunch.io/api/datasets"),
                    a)
            )
            expect_no_request(
                expect_identical(GET("https://app.crunch.io/api/",
                    query=list(user="me")), b)
            )
        })
    })
    with_fake_http({
        test_that("POSTing to a different resource doesn't bust cache", {
            expect_POST(p1 <- POST("https://app.crunch.io/api/"),
                "https://app.crunch.io/api/")
        })
    })
    without_internet({
        test_that("Cache was unaffected by that", {
            ## Now read from cache
            expect_no_request(
                expect_identical(GET("https://app.crunch.io/api/datasets"),
                    a)
            )
            expect_no_request(
                expect_identical(GET("https://app.crunch.io/api/",
                    query=list(user="me")), b)
            )
        })
    })
    with_fake_http({
        test_that("POSTing busts cache narrowly", {
            expect_POST(p2 <- POST("https://app.crunch.io/api/datasets"),
                "https://app.crunch.io/api/datasets")
        })
    })
    without_internet({
        test_that("Only that resource had its cache busted", {
            expect_GET(GET("https://app.crunch.io/api/datasets"),
                "https://app.crunch.io/api/datasets")
            expect_no_request(
                expect_identical(GET("https://app.crunch.io/api/",
                    query=list(user="me")), b)
            )
        })
    })

    test_that("cacheOff stops caching and clears existing cache", {
        clearCache() ## So we're clean
        with_fake_http({
            expect_GET(GET("https://app.crunch.io/api/datasets"))
        })
        expect_length(cacheKeys(), 1)
        cacheOff()
        on.exit(cacheOn()) ## Turn it back on
        expect_length(cacheKeys(), 0)
        with_fake_http({
            expect_GET(a <- GET("https://app.crunch.io/api/datasets"))
        })
        expect_length(cacheKeys(), 0)
        expect_identical(a$url, "https://app.crunch.io/api/datasets")
    })

    test_that("Requests with an invalid URL return a useful error", {
        expect_error(GET(NULL), "Invalid URL: NULL")
        expect_error(cachedPOST(table(1:5)),
            "Invalid URL: c(1, 1, 1, 1, 1)",
            fixed=TRUE)
        setClass("TestS4Obj", contains="environment")
        expect_error(GET(new("TestS4Obj")),
            'Invalid URL.*TestS4Obj')
    })
})

Try the httpcache package in your browser

Any scripts or data that you put into this service are public.

httpcache documentation built on Jan. 13, 2021, 7:46 p.m.