Skip to content

Commit

Permalink
WIP #152: dataset_detail
Browse files Browse the repository at this point in the history
  • Loading branch information
florianm committed Mar 10, 2024
1 parent 057f65f commit c181901
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 0 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export(attachment_get)
export(attachment_link)
export(attachment_list)
export(audit_get)
export(dataset_detail)
export(dataset_list)
export(drop_null_coords)
export(encryption_key_list)
Expand Down
88 changes: 88 additions & 0 deletions R/dataset_detail.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#' List all datasets of one project.
#'
#' While the API endpoint will return all datasets for one project,
#' \code{\link{dataset_list}} will fail with incorrect or missing
#' authentication.
#'
#' A Dataset is a named collection of Entities that have the same properties.
#' A Dataset can be linked to Forms as Attachments. This will make it available
#' to clients as an automatically-updating CSV.
#'
#' This function is supported from ODK Central v2022.3 and will warn if the
#' given odkc_version is lower.
#'
#' `r lifecycle::badge("maturing")`
#'
#' @template param-pid
#' @param did (chr) The dataset name.
#' @template param-url
#' @template param-auth
#' @template param-retries
#' @template param-odkcv
#' @template param-orders
#' @template param-tz
#' @return A list of lists following the exact format and naming of the API
#' response. Since this nested list is so deeply nested and irregularly shaped
#' it is not trivial to rectangle the result into a tibble.
# nolint start
#' @seealso \url{ https://docs.getodk.org/central-api-dataset-management/#datasets}
# nolint end
#' @family dataset-management
#' @export
#' @examples
#' \dontrun{
#' # See vignette("setup") for setup and authentication options
#' # ruODK::ru_setup(svc = "....svc", un = "[email protected]", pw = "...")
#'
#' ds <- dataset_list(pid = get_default_pid())
#' ds1 <- dataset_detail(pid = get_default_pid(), did = ds$name[1])
#'
#' ds1 |> listviewer::jsonedit()
#' ds1$linkedForms |> purrr::list_transpose() |> tibble::as_tibble()
#' ds1$sourceForms |> purrr::list_transpose() |> tibble::as_tibble()
#' ds1$properties |> purrr::list_transpose() |> tibble::as_tibble()
#' }
dataset_detail <- function(pid = get_default_pid(),
did = NULL,
url = get_default_url(),
un = get_default_un(),
pw = get_default_pw(),
retries = get_retries(),
odkc_version = get_default_odkc_version(),
orders = c(
"YmdHMS",
"YmdHMSz",
"Ymd HMS",
"Ymd HMSz",
"Ymd",
"ymd"
),
tz = get_default_tz()) {
yell_if_missing(url, un, pw, pid = pid)

if (is.null(did))
ru_msg_abort("dataset_detail requires the dataset names as 'did=\"name\"'.")

if (odkc_version |> semver_lt("2022.3")) {
ru_msg_warn("dataset_detail is supported from v2022.3")
}

ds <- httr::RETRY(
"GET",
httr::modify_url(url,
path = glue::glue(
"v1/projects/{pid}/datasets/",
"{URLencode(did, reserved = TRUE)}"
)),
httr::add_headers(
"Accept" = "application/json",
"X-Extended-Metadata" = "true"
),
httr::authenticate(un, pw),
times = retries
) |>
yell_if_error(url, un, pw) |>
httr::content(encoding="utf-8")
}

# usethis::use_test("dataset_detail") # nolint
117 changes: 117 additions & 0 deletions man/dataset_detail.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/dataset_list.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions tests/testthat/test-dataset_detail.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
test_that("dataset_detail works", {

ds <- dataset_list(pid = get_default_pid(),
url = get_test_url(),
un = get_test_un(),
pw = get_test_pw(),
odkc_version = get_test_odkc_version())

ds1 <- dataset_detail(pid = get_default_pid(),
did = ds$name[1],
url = get_test_url(),
un = get_test_un(),
pw = get_test_pw(),
odkc_version = get_test_odkc_version())

# dataset_detail returns a list
testthat::expect_is(ds1, "list")

# linkedForms contain form xmlFormId and name
lf <- ds1$linkedForms |> purrr::list_transpose() |> tibble::as_tibble()
testthat::expect_equal(names(lf), c("xmlFormId", "name" ))

# sourceForms contain form xmlFormId and name
sf <- ds1$sourceForms |> purrr::list_transpose() |> tibble::as_tibble()
testthat::expect_equal(names(sf), c("xmlFormId", "name" ))

# properties lists attributes of entities
pr <- ds1$properties |> purrr::list_transpose() |> tibble::as_tibble()
testthat::expect_equal(names(pr), c("name", "publishedAt", "odataName", "forms"))
})


test_that("dataset_detail warns if odkc_version too low", {
skip_if(Sys.getenv("ODKC_TEST_URL") == "",
message = "Test server not configured"
)

ds <- dataset_list(pid = get_default_pid(),
url = get_test_url(),
un = get_test_un(),
pw = get_test_pw(),
odkc_version = "2022.3")

ds1 <- dataset_detail(
pid = get_test_pid(),
did = ds$name[1],
url = get_test_url(),
un = get_test_un(),
pw = get_test_pw(),
odkc_version = "2022.3"
)

testthat::expect_warning(
ds1 <- dataset_detail(
pid = get_test_pid(),
did = ds$name[1],
url = get_test_url(),
un = get_test_un(),
pw = get_test_pw(),
odkc_version = "1.5.3"
)
)

})

0 comments on commit c181901

Please sign in to comment.