tests/testthat/test-SecurityHeaders_helpers.R

test_that("validate_csp handles NULL input correctly", {
  # Should return NULL when input is NULL
  expect_null(validate_csp(NULL))
})

test_that("validate_csp validates input types", {
  # Invalid input types should error
  expect_snapshot(validate_csp("not a list"), error = TRUE)
  expect_snapshot(validate_csp(list(invalid_directive = "value")), error = TRUE)
})

test_that("validate_csp accepts valid CSP directives created with csp()", {
  # Simple valid CSP
  valid_csp <- csp(
    default_src = "self",
    script_src = c("self", "https://example.com"),
    style_src = c("self", "unsafe-inline")
  )

  result <- validate_csp(valid_csp)
  expect_type(result, "list")
  expect_equal(length(result), 3)
  expect_equal(result$default_src, "'self'")
  expect_equal(result$script_src, c("'self'", "https://example.com"))
  expect_equal(result$style_src, c("'self'", "'unsafe-inline'"))
})

test_that("validate_csp adds single quotes to special keywords", {
  # Test that special keywords get quoted correctly
  csp_with_keywords <- csp(
    script_src = c("self", "none", "unsafe-inline", "unsafe-eval", "https://example.com")
  )

  result <- validate_csp(csp_with_keywords)
  expect_equal(
    result$script_src,
    c("'self'", "'none'", "'unsafe-inline'", "'unsafe-eval'", "https://example.com")
  )
})

test_that("validate_csp normalizes quoted values", {
  # Test that already quoted values are handled correctly
  csp_with_quotes <- csp(
    script_src = c("'self'", "self", "'none'", "none")
  )

  result <- validate_csp(csp_with_quotes)
  expect_equal(
    result$script_src,
    c("'self'", "'self'", "'none'", "'none'")
  )
})

test_that("validate_csp warns about inapplicable directives", {
  # unsafe-eval is not applicable to style_src
  expect_snapshot(
    validate_csp(csp(style_src = c("self", "unsafe-eval")))
  )

  # Check that the inapplicable value is removed
  result <- suppressWarnings(validate_csp(csp(style_src = c("self", "unsafe-eval"))))
  expect_equal(result$style_src, "'self'")
})

test_that("validate_csp warns about superseeded directives", {
  # strict-dynamic superseeds self and unsafe-inline in script_src
  expect_snapshot(
    validate_csp(csp(script_src = c("self", "unsafe-inline", "strict-dynamic")))
  )

  # Check that superseeded values are removed
  result <- suppressWarnings(
    validate_csp(csp(script_src = c("self", "unsafe-inline", "strict-dynamic")))
  )
  expect_equal(result$script_src, "'strict-dynamic'")
})

test_that("validate_csp handles nonce values", {
  # Test nonce values are properly handled
  nonce_csp <- csp(script_src = c("self", "nonce-abcdef123456"))

  result <- validate_csp(nonce_csp)
  expect_equal(result$script_src, c("'self'", "'nonce-abcdef123456'"))
})

test_that("validate_csp handles hash values", {
  # Test hash values are properly handled
  hash_csp <- csp(
    script_src = c(
      "self",
      "sha256-abcdef123456",
      "sha384-abcdef123456",
      "sha512-abcdef123456"
    )
  )

  result <- validate_csp(hash_csp)
  expect_equal(
    result$script_src,
    c("'self'", "'sha256-abcdef123456'", "'sha384-abcdef123456'", "'sha512-abcdef123456'")
  )
})

test_that("validate_csp handles empty elements", {
  # Test that empty elements are removed
  csp_with_empty <- csp(
    default_src = "self",
    script_src = character(0),
    style_src = NULL
  )

  result <- validate_csp(csp_with_empty)
  expect_equal(names(result), "default_src")
  expect_equal(result$default_src, "'self'")
})

test_that("validate_csp handles complex real-world examples", {
  # Test a more complex real-world CSP example
  complex_csp <- csp(
    default_src = "none",
    script_src = c("self", "strict-dynamic", "https://example.com"),
    style_src = c("self", "unsafe-inline"),
    img_src = c("self", "data:"),
    connect_src = "self",
    font_src = c("self", "https://fonts.gstatic.com"),
    frame_ancestors = "none",
    base_uri = "self",
    form_action = "self",
    upgrade_insecure_requests = TRUE
  )

  # We expect a warning about strict-dynamic superseeding self
  expect_snapshot(
    validate_csp(complex_csp)
  )

  # Check the result (suppressing the expected warning)
  result <- suppressWarnings(validate_csp(complex_csp))
  expect_equal(length(result), 10)
  expect_equal(result$default_src, "'none'")
  expect_equal(result$script_src, c("'strict-dynamic'"))
  expect_equal(result$frame_ancestors, "'none'")
  expect_equal(result$upgrade_insecure_requests, "")
})

test_that("validate_csp handles boolean flag directives", {
  # Test boolean flag directives like sandbox, require_trusted_types_for and upgrade_insecure_requests
  boolean_flags_csp <- csp(
    default_src = "self",
    sandbox = TRUE,
    require_trusted_types_for = TRUE,
    upgrade_insecure_requests = TRUE
  )

  expect_equal(boolean_flags_csp$sandbox, "")
  expect_equal(boolean_flags_csp$require_trusted_types_for, "")
  expect_equal(boolean_flags_csp$upgrade_insecure_requests, "")
})

Try the firesafety package in your browser

Any scripts or data that you put into this service are public.

firesafety documentation built on Sept. 10, 2025, 10:27 a.m.