Nothing
library(testthat)
library(AutoDeskR)
# aps_request ---------------------------------------------------------------
test_that("aps_request builds a request with the correct URL", {
req <- AutoDeskR:::aps_request("https://example.com")
expect_s3_class(req, "httr2_request")
expect_equal(req$url, "https://example.com")
})
test_that("aps_request adds Authorization header when token is provided", {
req <- AutoDeskR:::aps_request("https://example.com", token = "mytoken")
# httr2 redacts Authorization values as a security measure; check presence via names()
expect_true("Authorization" %in% names(req$headers))
})
test_that("aps_request omits Authorization header when token is NULL", {
req <- AutoDeskR:::aps_request("https://example.com", token = NULL)
expect_false("Authorization" %in% names(req$headers))
})
test_that("aps_request sets explicit HTTP method", {
req <- AutoDeskR:::aps_request("https://example.com", method = "POST")
expect_equal(req$method, "POST")
})
test_that("aps_request leaves method unset (GET default) when method = 'GET'", {
req <- AutoDeskR:::aps_request("https://example.com", method = "GET")
# httr2 uses NULL to represent the default GET method
expect_true(is.null(req$method) || req$method == "GET")
})
# new_aps_token -------------------------------------------------------------
test_that("new_aps_token creates a correctly structured aps_token", {
parsed <- list(access_token = "tok123", token_type = "Bearer", expires_in = 3600L)
result <- AutoDeskR:::new_aps_token(parsed, "https://example.com", list())
expect_s3_class(result, "aps_token")
expect_s3_class(result, "getToken")
expect_equal(result$access_token, "tok123")
expect_equal(result$token_type, "Bearer")
expect_equal(result$expires_in, 3600L)
expect_equal(result$path, "https://example.com")
expect_true(result$expires_at > Sys.time())
expect_true(result$fetched_at <= Sys.time())
})
test_that("new_aps_token sets expires_at roughly expires_in - 60 seconds ahead", {
parsed <- list(access_token = "tok", token_type = "Bearer", expires_in = 3600L)
before <- Sys.time()
result <- AutoDeskR:::new_aps_token(parsed, "https://example.com", list())
after <- Sys.time()
expect_gte(as.numeric(result$expires_at - before, units = "secs"), 3600 - 60 - 1)
expect_lte(as.numeric(result$expires_at - after, units = "secs"), 3600 - 60 + 1)
})
# .resolve_token ------------------------------------------------------------
test_that(".resolve_token returns plain strings unchanged", {
expect_equal(AutoDeskR:::.resolve_token("mytoken"), "mytoken")
})
test_that(".resolve_token extracts access_token from a valid aps_token", {
tok <- structure(
list(access_token = "abc123", expires_at = Sys.time() + 3600),
class = c("aps_token", "getToken")
)
expect_equal(AutoDeskR:::.resolve_token(tok), "abc123")
})
test_that(".resolve_token warns when aps_token is expired", {
tok <- structure(
list(access_token = "abc123", expires_at = Sys.time() - 1),
class = c("aps_token", "getToken")
)
expect_warning(AutoDeskR:::.resolve_token(tok), "expired")
})
test_that(".resolve_token still returns the token string when expired", {
tok <- structure(
list(access_token = "abc123", expires_at = Sys.time() - 1),
class = c("aps_token", "getToken")
)
result <- suppressWarnings(AutoDeskR:::.resolve_token(tok))
expect_equal(result, "abc123")
})
# aps_perform ---------------------------------------------------------------
test_that("aps_perform returns the response object on success", {
mock_resp <- structure(list(status_code = 200L), class = "httr2_response")
local_mocked_bindings(
req_perform = function(req, ...) mock_resp,
.package = "AutoDeskR"
)
result <- AutoDeskR:::aps_perform(httr2::request("https://example.com"))
expect_equal(result, mock_resp)
})
test_that("aps_perform converts httr2_http errors into aps_error conditions", {
mock_resp <- structure(list(status_code = 401L), class = "httr2_response")
mock_err <- structure(
list(message = "HTTP 401 Unauthorized", resp = mock_resp),
class = c("httr2_http_401", "httr2_http", "error", "condition")
)
local_mocked_bindings(
req_perform = function(req, ...) stop(mock_err),
resp_body_json = function(resp, ...) list(message = "Unauthorized"),
resp_status = function(resp, ...) 401L,
.package = "AutoDeskR"
)
err <- tryCatch(
AutoDeskR:::aps_perform(httr2::request("https://example.com")),
aps_error = function(e) e
)
expect_s3_class(err, "aps_error")
expect_equal(err$status, 401L)
expect_match(err$message, "401")
expect_match(err$message, "Unauthorized")
})
test_that("aps_perform falls back to conditionMessage when body has no message field", {
mock_resp <- structure(list(status_code = 500L), class = "httr2_response")
mock_err <- structure(
list(message = "Internal Server Error", resp = mock_resp),
class = c("httr2_http_500", "httr2_http", "error", "condition")
)
local_mocked_bindings(
req_perform = function(req, ...) stop(mock_err),
resp_body_json = function(resp, ...) list(), # no message or reason
resp_status = function(resp, ...) 500L,
.package = "AutoDeskR"
)
err <- tryCatch(
AutoDeskR:::aps_perform(httr2::request("https://example.com")),
aps_error = function(e) e
)
expect_s3_class(err, "aps_error")
expect_equal(err$status, 500L)
expect_match(err$message, "Internal Server Error")
})
test_that("aps_perform uses reason field when message field is absent", {
mock_resp <- structure(list(status_code = 403L), class = "httr2_response")
mock_err <- structure(
list(message = "HTTP 403", resp = mock_resp),
class = c("httr2_http_403", "httr2_http", "error", "condition")
)
local_mocked_bindings(
req_perform = function(req, ...) stop(mock_err),
resp_body_json = function(resp, ...) list(reason = "Forbidden"),
resp_status = function(resp, ...) 403L,
.package = "AutoDeskR"
)
err <- tryCatch(
AutoDeskR:::aps_perform(httr2::request("https://example.com")),
aps_error = function(e) e
)
expect_match(err$message, "Forbidden")
})
# aps_error -----------------------------------------------------------------
test_that("aps_error creates condition with correct class", {
err <- aps_error("something went wrong", status = 401L, body = list())
expect_s3_class(err, "aps_error")
expect_s3_class(err, "error")
expect_s3_class(err, "condition")
})
test_that("aps_error stores message, status, and body", {
body <- list(message = "Unauthorized", reason = "bad token")
err <- aps_error("APS API error (HTTP 401): Unauthorized", status = 401L, body = body)
expect_equal(err$message, "APS API error (HTTP 401): Unauthorized")
expect_equal(err$status, 401L)
expect_equal(err$body, body)
})
test_that("aps_error can be caught with tryCatch", {
result <- tryCatch(
stop(aps_error("oops", status = 500L, body = list())),
aps_error = function(e) paste("caught:", e$status)
)
expect_equal(result, "caught: 500")
})
# is_expired ----------------------------------------------------------------
test_that("is_expired returns FALSE for a fresh token", {
tok <- structure(
list(
access_token = "tok",
token_type = "Bearer",
expires_in = 3600L,
expires_at = Sys.time() + 3600,
fetched_at = Sys.time(),
path = "https://example.com",
response = list()
),
class = c("aps_token", "getToken")
)
expect_false(is_expired(tok))
})
test_that("is_expired returns TRUE for an expired token", {
tok <- structure(
list(
access_token = "tok",
token_type = "Bearer",
expires_in = 1L,
expires_at = Sys.time() - 1,
fetched_at = Sys.time() - 3601,
path = "https://example.com",
response = list()
),
class = c("aps_token", "getToken")
)
expect_true(is_expired(tok))
})
# $.aps_token backward-compat shim -----------------------------------------
test_that("$.aps_token shim: resp$content$access_token works", {
tok <- structure(
list(
access_token = "abc123",
token_type = "Bearer",
expires_in = 3600L,
expires_at = Sys.time() + 3600,
fetched_at = Sys.time(),
path = "https://example.com",
response = list()
),
class = c("aps_token", "getToken")
)
expect_equal(tok$content$access_token, "abc123")
expect_equal(tok$content$token_type, "Bearer")
expect_equal(tok$content$expires_in, 3600L)
})
test_that("$.aps_token shim: direct field access also works", {
tok <- structure(
list(
access_token = "abc123",
token_type = "Bearer",
expires_in = 3600L,
expires_at = Sys.time() + 3600,
fetched_at = Sys.time(),
path = "https://example.com",
response = list()
),
class = c("aps_token", "getToken")
)
expect_equal(tok$access_token, "abc123")
expect_equal(tok$path, "https://example.com")
})
# waitForFile ---------------------------------------------------------------
test_that("waitForFile returns immediately when checkFile reports success", {
mock_resp <- structure(
list(content = list(status = "success"), path = "x", response = list()),
class = "checkFile"
)
local_mocked_bindings(
checkFile = function(...) mock_resp,
.package = "AutoDeskR"
)
result <- waitForFile("SOME_URN", "some_token", verbose = FALSE)
expect_s3_class(result, "checkFile")
expect_equal(result$content$status, "success")
})
test_that("waitForFile returns on failed status", {
mock_resp <- structure(
list(content = list(status = "failed"), path = "x", response = list()),
class = "checkFile"
)
local_mocked_bindings(
checkFile = function(...) mock_resp,
.package = "AutoDeskR"
)
result <- waitForFile("SOME_URN", "some_token", verbose = FALSE)
expect_equal(result$content$status, "failed")
})
test_that("waitForFile times out when status never reaches a terminal state", {
mock_resp <- structure(
list(content = list(status = "inprogress"), path = "x", response = list()),
class = "checkFile"
)
local_mocked_bindings(
checkFile = function(...) mock_resp,
.package = "AutoDeskR"
)
expect_error(
waitForFile("SOME_URN", "some_token", interval = 0, timeout = -1, verbose = FALSE),
"timed out"
)
})
test_that("waitForFile via httptest2 returns on first poll when status is success", {
skip_on_cran()
skip_if_not(dir.exists(test_path("developer.api.autodesk.com")), "mock fixtures not available")
skip_if_not_installed("httptest2")
httptest2::with_mock_api({
resp <- waitForFile(urn = "ENCODED_URN", token = "test_token", verbose = FALSE)
expect_s3_class(resp, "checkFile")
expect_equal(resp$content$status, "success")
})
})
# waitForWorkItem -----------------------------------------------------------
test_that("waitForWorkItem returns immediately when checkPdf reports success", {
mock_resp <- structure(
list(content = list(status = "success"), path = "x", response = list()),
class = "checkPdf"
)
local_mocked_bindings(
checkPdf = function(...) mock_resp,
.package = "AutoDeskR"
)
result <- waitForWorkItem("wi-001", "some_token", verbose = FALSE)
expect_s3_class(result, "checkPdf")
expect_equal(result$content$status, "success")
})
test_that("waitForWorkItem keeps polling while status is inprogress then returns", {
call_count <- 0L
local_mocked_bindings(
checkPdf = function(...) {
call_count <<- call_count + 1L
status <- if (call_count < 3L) "inprogress" else "success"
structure(list(content = list(status = status), path = "x", response = list()),
class = "checkPdf")
},
.package = "AutoDeskR"
)
result <- waitForWorkItem("wi-001", "some_token", interval = 0, verbose = FALSE)
expect_equal(result$content$status, "success")
expect_equal(call_count, 3L)
})
test_that("waitForWorkItem times out when status never leaves inprogress", {
mock_resp <- structure(
list(content = list(status = "inprogress"), path = "x", response = list()),
class = "checkPdf"
)
local_mocked_bindings(
checkPdf = function(...) mock_resp,
.package = "AutoDeskR"
)
expect_error(
waitForWorkItem("wi-001", "some_token", interval = 0, timeout = -1, verbose = FALSE),
"timed out"
)
})
test_that("waitForWorkItem via httptest2 returns on first poll when status is success", {
skip_on_cran()
skip_if_not(dir.exists(test_path("developer.api.autodesk.com")), "mock fixtures not available")
skip_if_not_installed("httptest2")
httptest2::with_mock_api({
resp <- waitForWorkItem(id = "abc123", token = "test_token", verbose = FALSE)
expect_s3_class(resp, "checkPdf")
expect_equal(resp$content$status, "success")
})
})
# as_tibble.listBuckets -----------------------------------------------------
test_that("as_tibble.listBuckets converts a multi-bucket response to a tibble", {
skip_if_not_installed("tibble")
resp <- structure(
list(content = list(items = list(
list(bucketKey = "b1", bucketOwner = "owner1", policyKey = "transient"),
list(bucketKey = "b2", bucketOwner = "owner2", policyKey = "persistent")
)), path = "x", response = list()),
class = "listBuckets"
)
tbl <- tibble::as_tibble(resp)
expect_s3_class(tbl, "tbl_df")
expect_named(tbl, c("bucketKey", "bucketOwner", "policyKey"))
expect_equal(nrow(tbl), 2L)
expect_equal(tbl$bucketKey, c("b1", "b2"))
expect_equal(tbl$policyKey, c("transient", "persistent"))
})
test_that("as_tibble.listBuckets returns a zero-row tibble for empty items", {
skip_if_not_installed("tibble")
resp <- structure(
list(content = list(items = list()), path = "x", response = list()),
class = "listBuckets"
)
tbl <- tibble::as_tibble(resp)
expect_s3_class(tbl, "tbl_df")
expect_equal(nrow(tbl), 0L)
expect_named(tbl, c("bucketKey", "bucketOwner", "policyKey"))
})
test_that("as_tibble.listBuckets via httptest2 returns a tibble with correct columns", {
skip_on_cran()
skip_if_not_installed("tibble")
skip_if_not(dir.exists(test_path("developer.api.autodesk.com")), "mock fixtures not available")
skip_if_not_installed("httptest2")
httptest2::with_mock_api({
resp <- listBuckets(token = "test_token")
tbl <- tibble::as_tibble(resp)
expect_s3_class(tbl, "tbl_df")
expect_named(tbl, c("bucketKey", "bucketOwner", "policyKey"))
expect_equal(tbl$bucketKey[[1]], "mybucket")
})
})
test_that("as_tibble.listBuckets errors without tibble", {
resp <- structure(
list(content = list(items = list()), path = "x", response = list()),
class = "listBuckets"
)
skip_if(requireNamespace("tibble", quietly = TRUE), "tibble is installed")
expect_error(tibble::as_tibble(resp), "Package 'tibble' needed")
})
# as_tibble.listObjects -----------------------------------------------------
test_that("as_tibble.listObjects converts a multi-object response to a tibble", {
skip_if_not_installed("tibble")
resp <- structure(
list(content = list(items = list(
list(objectKey = "aerial.dwg", objectId = "id1", size = 1024L, location = "loc1"),
list(objectKey = "model.rvt", objectId = "id2", size = 20480L, location = "loc2")
)), path = "x", response = list()),
class = "listObjects"
)
tbl <- tibble::as_tibble(resp)
expect_s3_class(tbl, "tbl_df")
expect_named(tbl, c("objectKey", "objectId", "size", "location"))
expect_equal(nrow(tbl), 2L)
expect_equal(tbl$objectKey, c("aerial.dwg", "model.rvt"))
expect_equal(tbl$size, c(1024L, 20480L))
})
test_that("as_tibble.listObjects returns a zero-row tibble for empty items", {
skip_if_not_installed("tibble")
resp <- structure(
list(content = list(items = list()), path = "x", response = list()),
class = "listObjects"
)
tbl <- tibble::as_tibble(resp)
expect_equal(nrow(tbl), 0L)
expect_named(tbl, c("objectKey", "objectId", "size", "location"))
})
test_that("as_tibble.listObjects via httptest2 returns a tibble with correct columns", {
skip_on_cran()
skip_if_not_installed("tibble")
skip_if_not(dir.exists(test_path("developer.api.autodesk.com")), "mock fixtures not available")
skip_if_not_installed("httptest2")
httptest2::with_mock_api({
resp <- listObjects(token = "test_token", bucket = "mybucket")
tbl <- tibble::as_tibble(resp)
expect_s3_class(tbl, "tbl_df")
expect_named(tbl, c("objectKey", "objectId", "size", "location"))
expect_equal(tbl$objectKey[[1]], "aerial.dwg")
expect_equal(tbl$size[[1]], 1024L)
})
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.