diff --git a/DESCRIPTION b/DESCRIPTION index d4b45e1..69513e9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: sentryR Type: Package -Title: Send Errors and Messages to Sentry +Title: Send Errors and Messages to 'Sentry' Version: 1.0.0 Authors@R: c( person("Joao", "Santiago", email = "santiago@billie.io", role = c("aut", "cre")), @@ -14,7 +14,7 @@ LazyData: true ByteCompile: true URL: https://github.com/ozean12/sentryR BugReports: https://github.com/ozean12/sentryR/issues -RoxygenNote: 7.0.1 +RoxygenNote: 7.0.2 Imports: httr, jsonlite, @@ -26,4 +26,5 @@ Suggests: covr, httptest, mockery, - testthat (>= 2.1.0) + testthat (>= 2.1.0), + plumber diff --git a/R/zzz.R b/R/zzz.R index ed04364..5961caa 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -2,6 +2,7 @@ # pre-calculates a couple of re-used values # plays well with the glue package too .sentry_env <- new.env() + # FIXME: should use utils::packageVersion() instead, but that's not working # with CRAN because the package is checked before being installed, thus there is # no sentryR package to get the version from diff --git a/tests/testthat/helper-mocks.R b/tests/testthat/helper-mocks.R new file mode 100644 index 0000000..714fd24 --- /dev/null +++ b/tests/testthat/helper-mocks.R @@ -0,0 +1,13 @@ +# mock request +# From the plumber tests +# https://github.com/rstudio/plumber/blob/master/tests/testthat/helper-mock-request.R +make_req <- function(verb, path, qs = "", body = "") { + req <- new.env() + req$REQUEST_METHOD <- toupper(verb) + req$PATH_INFO <- path + req$QUERY_STRING <- qs + req$rook.input <- list(read_lines = function() { + body + }) + req +} diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R deleted file mode 100644 index 07b642c..0000000 --- a/tests/testthat/helper.R +++ /dev/null @@ -1 +0,0 @@ -library(httptest) diff --git a/tests/testthat/mocks.R b/tests/testthat/mocks.R deleted file mode 100644 index 5d7ad87..0000000 --- a/tests/testthat/mocks.R +++ /dev/null @@ -1,27 +0,0 @@ -# mock request -req <- list( - PATH_INFO = "/launch_eva01", - REQUEST_METHOD = "angel_attack", - postBody = '[{"battery_level": "5 min"}]', - HTTP_CONTENT_TYPE = "emergency launch", - HTTP_HOST = "central dogma" -) - -# mock error -error_nocalls <- simpleError("Reverse polarisation!!", - call = function() "He's dead Jim." -) - -error_wcalls <- simpleError("Reverse polarisation!!", - call = function() "He's dead Jim." -) - -# mock sentry DSN -.sentry_env <- new.env() -.sentry_env$public_key <- "1234" -.sentry_env$host <- "sentry.io" -.sentry_env$project_id <- "1" - -# mock response for sentry.configured -not_configured <- mockery::mock(FALSE) -configured <- mockery::mock(TRUE) diff --git a/tests/testthat/test-sentry.R b/tests/testthat/test-core.R similarity index 94% rename from tests/testthat/test-sentry.R rename to tests/testthat/test-core.R index 2326d30..be69c28 100644 --- a/tests/testthat/test-sentry.R +++ b/tests/testthat/test-core.R @@ -1,4 +1,4 @@ -context("test-sentry") +context("test-sentry-core") test_that("parsing the dsn works", { expect_error(parse_dsn(888)) @@ -41,9 +41,11 @@ test_that("setting configuration works", { expect_error(configure_sentry(42)) expect_error(configure_sentry(c("https://1234@sentry.io/1", "https://1234@sentry.io/2"))) - configure_sentry(dsn = "https://1234@sentry.io/1", - app_name = "el appo", app_version = "8.8.8", - environment = "production") + configure_sentry( + dsn = "https://1234@sentry.io/1", + app_name = "el appo", app_version = "8.8.8", + environment = "production" + ) expect_equal(.sentry_env$payload_skeleton$contexts$app$app_name, "el appo") expect_equal(.sentry_env$payload_skeleton$contexts$app$app_version, "8.8.8") @@ -57,7 +59,6 @@ test_that("setting configuration works", { expect_equal(.sentry_env$project_id, "1") rm(list = ls(envir = .sentry_env), envir = .sentry_env) - }) test_that("builds payload correctly", { @@ -119,6 +120,12 @@ test_that("we build the correct sentry.io call url", { }) test_that("we build the correct headers", { + + # No configuration yet + expect_error( + sentry_headers() + ) + # without deprecated secret key .sentry_env$public_key <- "1234" .sentry_env$secret_key <- NA diff --git a/tests/testthat/test-plumber_handlers.R b/tests/testthat/test-plumber_handlers.R new file mode 100644 index 0000000..de30319 --- /dev/null +++ b/tests/testthat/test-plumber_handlers.R @@ -0,0 +1,48 @@ +context("test handlers") + +test_that("default_error_handler works", { + mock_req <- make_req("angel_attack", "/launch_eva01", + body = '[{"battery_level": "5 min"}]' + ) + mock_res <- plumber:::PlumberResponse$new() + handled <- default_error_handler(mock_req, mock_res, simpleError("NO! NO! NO!")) + + expect_true( + is.list(handled) + ) + expect_equal( + names(handled), c("error") + ) + expect_equal( + handled$error, "500 - Internal server error" + ) + expect_equal( + mock_res$status, 500 + ) + + options(plumber.debug = TRUE) + mock_res$status <- 200 + handled <- default_error_handler(mock_req, mock_res, simpleError("NO! NO! NO!")) + + expect_equal( + names(handled), c("error", "message") + ) + expect_equal( + handled$error, "500 - Internal server error" + ) + expect_equal( + handled$message, "Error: NO! NO! NO!\n" + ) + + # Now with status already set to 500 + handled <- default_error_handler(mock_req, mock_res, simpleError("NO! NO! NO!")) + expect_equal( + handled$error, "Internal error" + ) +}) + +test_that("we can wrap error handlers with sentry", { + wrapped <- wrap_error_handler_with_sentry() + + expect_true(is.function(wrapped)) +})