test_that("batch retrieval preserves duplicates and caches absent abstracts", {
count <- 0L
callback <- function(url, headers, params, timeout) {
count <<- count + 1L
if (grepl("missing", url, fixed = TRUE)) {
return(list(message = list()))
}
list(message = list(abstract = "Found"))
}
cache <- new_crossref_cache()
dois <- c("10.1000/FOUND", " 10.1000/found ", "10.1000/missing",
"10.1000/MISSING", "", NA_character_)
result <- get_abstracts_from_dois(
dois, cache = cache, requester = callback, min_interval = 0
)
expect_identical(names(result), dois)
expect_length(result, length(dois))
expect_identical(result[[1]], "Found")
expect_identical(result[[2]], "Found")
expect_null(result[[3]])
expect_null(result[[4]])
expect_null(result[[5]])
expect_null(result[[6]])
expect_equal(count, 2L)
again <- get_abstracts_from_dois(
dois, cache = cache, requester = callback, min_interval = 0
)
expect_identical(again, result)
expect_equal(count, 2L)
})
test_that("batch throttles distinct uncached requests only", {
count <- 0L
delays <- numeric()
callback <- function(url, headers, params, timeout) {
count <<- count + 1L
list(message = list(abstract = "Abstract"))
}
clock <- function(seconds) delays <<- c(delays, seconds)
get_abstracts_from_dois(
c("10.1000/a", "10.1000/a", "10.1000/b", "10.1000/c"),
requester = callback, sleep = clock, min_interval = 0.4
)
expect_equal(count, 3L)
expect_equal(delays, c(0.4, 0.4))
})
test_that("mailto is forwarded and metadata is preserved during enrichment", {
callback <- function(url, headers, params, timeout) {
expect_equal(params$mailto, "research@example.org")
expect_match(headers[["User-Agent"]], "abstractExtractR", fixed = TRUE)
list(message = list(abstract = "Recovered"))
}
original <- list(one = Article(
title = "Paper", authors = c("Alice", "Bob"),
abstract = NULL, doi = "10.1000/a"
))
output <- enrich_articles_with_crossref(
original, requester = callback, mailto = "research@example.org",
min_interval = 0
)
expect_identical(names(output), names(original))
expect_identical(output$one$abstract, "Recovered")
expect_identical(output$one$authors, c("Alice", "Bob"))
expect_null(original$one$abstract)
})
test_that("failed lookups are not stored in reusable cache", {
cache <- new_crossref_cache()
count <- 0L
callback <- function(url, headers, params, timeout) {
count <<- count + 1L
if (count == 1L) stop("temporary failure")
list(message = list(abstract = "Recovered"))
}
first <- get_abstracts_from_dois(
"10.1000/a", cache = cache, requester = callback,
on_error = "skip", min_interval = 0
)
expect_null(first[[1]])
second <- get_abstracts_from_dois(
"10.1000/a", cache = cache, requester = callback, min_interval = 0
)
expect_identical(second[[1]], "Recovered")
expect_equal(count, 2L)
})
test_that("invalid inputs fail before HTTP", {
callback <- function(url, headers, params, timeout) {
fail("no request expected")
}
expect_error(get_abstracts_from_dois(10, requester = callback), "character")
expect_error(get_abstracts_from_dois("x", cache = list(),
requester = callback), "cache")
expect_error(get_abstracts_from_dois("x", max_tries = 0,
requester = callback), "max_tries")
expect_error(get_abstracts_from_dois("x", min_interval = -1,
requester = callback), "min_interval")
expect_error(get_abstracts_from_dois("x", requester = callback,
sleep = "wrong"), "sleep")
expect_error(get_abstracts_from_dois("x", requester = callback,
mailto = "not-an-email"), "mailto")
expect_identical(get_abstracts_from_dois(character(),
requester = callback), list())
})