From afa036c4a8086f130b9e2e1fadbdc3171bf5646f Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Fri, 26 Jan 2024 01:24:41 -0800 Subject: [PATCH] fix #5 add tests mocking requests, add suggest pkgs jsonlite and webmockr --- DESCRIPTION | 2 + tests/testthat/helper-proofr.R | 1 + tests/testthat/helper-stubs.R | 59 ++++++++++++++++++++++++ tests/testthat/test-proof_authenticate.R | 41 ++++++++++++++++ tests/testthat/test-proof_cancel.R | 43 +++++++++++++++++ tests/testthat/test-proof_header.R | 4 +- tests/testthat/test-proof_start.R | 41 ++++++++++++++++ tests/testthat/test-proof_status.R | 55 ++++++++++++++++++++++ 8 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 tests/testthat/helper-proofr.R create mode 100644 tests/testthat/helper-stubs.R create mode 100644 tests/testthat/test-proof_authenticate.R create mode 100644 tests/testthat/test-proof_cancel.R create mode 100644 tests/testthat/test-proof_start.R create mode 100644 tests/testthat/test-proof_status.R diff --git a/DESCRIPTION b/DESCRIPTION index d33baa9..59f9a40 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -15,9 +15,11 @@ Imports: glue, httr Suggests: + jsonlite, knitr, rmarkdown, testthat (>= 3.0.0), + webmockr, withr Config/testthat/edition: 3 VignetteBuilder: knitr diff --git a/tests/testthat/helper-proofr.R b/tests/testthat/helper-proofr.R new file mode 100644 index 0000000..4e437d4 --- /dev/null +++ b/tests/testthat/helper-proofr.R @@ -0,0 +1 @@ +library(webmockr) diff --git a/tests/testthat/helper-stubs.R b/tests/testthat/helper-stubs.R new file mode 100644 index 0000000..e5162ca --- /dev/null +++ b/tests/testthat/helper-stubs.R @@ -0,0 +1,59 @@ +response_status_running <- list( + canJobStart = FALSE, + jobStatus = "RUNNING", + cromwellUrl = "https://some.url", + jobInfo = list( + WORKFLOWLOGDIR = "/some/path", + SCRATCHDIR = "/some/path", + SLURM_JOB_ID = "someid", + CROMWELL_DIR = "/some/path", + SERVERLOGDIR = "/some/path", + SINGULARITY_CACHEDIR = "/some/path", + SERVERTIME = "1-0", + USE_AWS = FALSE, + SLURM_JOB_ACCOUNT = "/some/path" + ) +) + +response_status_not_running <- list( + canJobStart = TRUE, + jobStatus = NULL, + cromwellUrl = NULL, + jobInfo = list( + WORKFLOWLOGDIR = NULL, + SCRATCHDIR = NULL, + SLURM_JOB_ID = NULL, + CROMWELL_DIR = NULL, + SERVERLOGDIR = NULL, + SINGULARITY_CACHEDIR = NULL, + SERVERTIME = NULL, + USE_AWS = NULL, + SLURM_JOB_ACCOUNT = NULL + ) +) + +response_start_success <- list( + job_id = "12345678", + info = "Job submitted successfully. Some message" +) + +response_start_conflict <- list( + message = "Job is already running" +) + +response_cancel_success <- list( + message = "Proof/cromwell job for user xxxxx has been cancelled" +) + +response_cancel_conflict <- list( + message = "Job is not running, nothing to delete" +) + +response_authenticate_success <- list( + username = "jane", + token = "somerandomstring", + server_url = NULL, + proxy_url = NULL, + job_id = NULL, + token_creation_date = NULL +) diff --git a/tests/testthat/test-proof_authenticate.R b/tests/testthat/test-proof_authenticate.R new file mode 100644 index 0000000..a8a3a6e --- /dev/null +++ b/tests/testthat/test-proof_authenticate.R @@ -0,0 +1,41 @@ +test_that("proof_authenticate - error behavior", { + # errors if no username supplied + expect_error(proof_authenticate(), + '"username" is missing') + + # errors if no password supplied + expect_error(proof_authenticate(username = "apple"), + '"password" is missing') + + # username should be character + expect_error(proof_authenticate(5), + 'username must be of class character') + + # password should be character + expect_error(proof_authenticate(username = "apple", password = 5), + 'password must be of class character') +}) + +test_that("proof_start - success", { + stub_registry_clear() + stub_request("post", make_url("authenticate")) %>% + to_return( + body = jsonlite::toJSON( + response_authenticate_success, auto_unbox = TRUE), + status = 200L, + headers = list('Content-type' = "application/json") + ) + stub_registry() + + enable(quiet = TRUE) + + auth_res <- proof_authenticate("jane", "faketoken") + + expect_type(auth_res, "character") + expect_equal(auth_res, "somerandomstring") + + + stub_registry_clear() + disable(quiet = TRUE) + Sys.unsetenv("PROOF_TOKEN") +}) diff --git a/tests/testthat/test-proof_cancel.R b/tests/testthat/test-proof_cancel.R new file mode 100644 index 0000000..481d900 --- /dev/null +++ b/tests/testthat/test-proof_cancel.R @@ -0,0 +1,43 @@ +test_that("proof_cancel - success", { + stub_registry_clear() + stub_request("delete", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON(response_cancel_success, auto_unbox = TRUE), + status = 200L, + headers = list('Content-type' = "application/json") + ) + stub_registry() + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + cancel_res <- proof_cancel() + }) + + expect_type(cancel_res, "list") + expect_type(cancel_res$message, "character") + expect_match(cancel_res$message, "cancelled") + + + stub_registry_clear() + disable(quiet = TRUE) +}) + +test_that("proof_cancel - not running, can not cancel", { + stub_request("delete", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON(response_cancel_conflict, auto_unbox = TRUE), + status = 409L, + headers = list('Content-type' = "application/json") + ) + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + expect_error(proof_cancel(), "Job is not running, nothing to delete") + }) + + + stub_registry_clear() + disable(quiet = TRUE) +}) diff --git a/tests/testthat/test-proof_header.R b/tests/testthat/test-proof_header.R index 40a4cf1..26f812c 100644 --- a/tests/testthat/test-proof_header.R +++ b/tests/testthat/test-proof_header.R @@ -8,7 +8,7 @@ test_that("proof_header", { expect_match(proof_header("adf")$headers[[1]], "adf") # If PROOF_TOKEN env var set, fxn can find it - withr::with_envvar(c("PROOF_TOKEN" = "world"), { - expect_match(proof_header()$headers[[1]], "world") + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + expect_match(proof_header()$headers[[1]], "notarealtoken") }) }) diff --git a/tests/testthat/test-proof_start.R b/tests/testthat/test-proof_start.R new file mode 100644 index 0000000..7319ebe --- /dev/null +++ b/tests/testthat/test-proof_start.R @@ -0,0 +1,41 @@ +test_that("proof_start - success", { + stub_request("post", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON(response_start_success, auto_unbox = TRUE), + status = 200L, + headers = list('Content-type' = "application/json") + ) + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + start_res <- proof_start() + }) + + expect_type(start_res, "list") + expect_type(start_res$job_id, "character") + expect_type(start_res$info, "character") + + + stub_registry_clear() + disable(quiet = TRUE) +}) + +test_that("proof_start - already running", { + stub_request("post", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON(response_start_conflict, auto_unbox = TRUE), + status = 409L, + headers = list('Content-type' = "application/json") + ) + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + expect_error(proof_start(), "Job is already running") + }) + + + stub_registry_clear() + disable(quiet = TRUE) +}) diff --git a/tests/testthat/test-proof_status.R b/tests/testthat/test-proof_status.R new file mode 100644 index 0000000..a081b09 --- /dev/null +++ b/tests/testthat/test-proof_status.R @@ -0,0 +1,55 @@ +test_that("proof_status - server IS running", { + stub_request("get", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON( + response_status_running, auto_unbox = TRUE, null = "null"), + status = 200L, + headers = list('Content-type' = "application/json") + ) + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + status_res <- proof_status() + }) + + expect_type(status_res, "list") + expect_type(status_res$canJobStart, "logical") + expect_type(status_res$jobStatus, "character") + expect_type(status_res$cromwellUrl, "character") + expect_type(status_res$jobInfo, "list") + for (item in status_res$jobInfo) { + expect_true(inherits(item, c("character", "logical"))) + } + + + stub_registry_clear() + disable(quiet = TRUE) +}) + +test_that("proof_status - server IS NOT running", { + stub_request("get", make_url("cromwell-server")) %>% + to_return( + body = jsonlite::toJSON( + response_status_not_running, auto_unbox = TRUE, null = "null"), + status = 200L, + headers = list('Content-type' = "application/json") + ) + + enable(quiet = TRUE) + + withr::with_envvar(c("PROOF_TOKEN" = "notarealtoken"), { + status_res <- proof_status() + }) + + expect_type(status_res, "list") + expect_type(status_res$canJobStart, "logical") + expect_null(status_res$jobStatus) + expect_null(status_res$cromwellUrl) + expect_type(status_res$jobInfo, "list") + for (item in status_res$jobInfo) expect_null(item) + + + stub_registry_clear() + disable(quiet = TRUE) +})