tempdir_file <- sanitize_path(withr::local_tempdir())
withr::local_envvar(R_USER_CACHE_DIR = tempdir_file)
# clean_redcap_log (Internal)
test_that("clean_redcap_log removes duplicates", {
  redcap_log <- data.frame(
    timestamp = c("2024-01-15 10:30:00",
                  "2024-01-15 10:30:00",
                  "2024-01-15 10:35:00"),
    username = c("user1", "user1", "user2"),
    action = c("Update record 123", "Update record 123", "Create record 456"),
    details = c("Field updated", "Field updated", "New record"),
    record = c("123", "123", "456"),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_identical(nrow(result), 2L)
})
test_that("clean_redcap_log trims whitespace", {
  redcap_log <- data.frame(
    timestamp = "2024-01-15 10:30:00",
    username = "  user1  ",
    action = "  Update record 123  ",
    details = "  Field updated  ",
    record = "123",
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_false(grepl("^\\s|\\s$", result$username[1L]))
  expect_false(grepl("^\\s|\\s$", result$action[1L]))
  expect_false(grepl("^\\s|\\s$", result$details[1L]))
})
test_that("clean_redcap_log identifies record actions", {
  redcap_log <- data.frame(
    timestamp = c(
      "2024-01-15 10:30:00",
      "2024-01-15 10:35:00",
      "2024-01-15 10:40:00",
      "2024-01-15 10:45:00"
    ),
    username = c("user1", "user2", "user3", "user4"),
    action = c(
      "Update record 123",
      "Delete record 456",
      "Create record 789",
      "Lock/Unlock Record 321"
    ),
    details = c("Updated", "Deleted", "Created", "Locked"),
    record = c("123", "456", "789", "321"),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  # Check that record_id was extracted and action_type was set
  expect_all_true(!is.na(result$action_type[1L:4L]))
  expect_all_true(
    result$action_type[1L:4L] %in%
      c("Update", "Delete", "Create", "Lock/Unlock")
  )
})
test_that("clean_redcap_log handles Manage/Design actions", {
  redcap_log <- data.frame(
    timestamp = c(
      "2024-01-15 10:30:00",
      "2024-01-15 10:35:00"
    ),
    username = c("user1", "user2"),
    action = c("Manage/Design", "Manage/Design"),
    details = c(
      "Edit project field: field_name",
      "Create project field: new_field"
    ),
    record = c(NA, NA),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_true(any(result$action_type == "Metadata Change Major", na.rm = TRUE))
})
test_that("clean_redcap_log converts [survey respondent] to NA", {
  redcap_log <- data.frame(
    timestamp = c("2024-01-15 10:35:00", "2024-01-15 10:30:00"),
    username = c("[survey respondent]", "user1"),
    action = c("Update record 123", "Create record 456"),
    details = c("Survey submitted", "Created"),
    record = c("123", "456"),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_s3_class(result, "data.frame")
  expect_true(is.na(result$username[1L]))
  expect_identical(result$username[2L], "user1")
})
test_that("clean_redcap_log sets action_type column", {
  redcap_log <- data.frame(
    timestamp = "2024-01-15 10:30:00",
    username = "user1",
    action = "Update record 123",
    details = "Updated",
    record = "123",
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_true("action_type" %in% colnames(result))
  expect_false(all(is.na(result$action_type)))
})
test_that("clean_redcap_log handles export actions", {
  redcap_log <- data.frame(
    timestamp = c(
      "2024-01-15 10:30:00",
      "2024-01-15 10:35:00"
    ),
    username = c("user1", "user2"),
    action = c("Data export", "Download uploaded file"),
    details = c("Exported data", "Downloaded file"),
    record = c(NA, NA),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_true(all(result$action_type %in% c("Exports", NA)))
})
test_that("clean_redcap_log handles user actions", {
  redcap_log <- data.frame(
    timestamp = c(
      "2024-01-15 10:30:00",
      "2024-01-15 10:35:00"
    ),
    username = c("user1", "user2"),
    action = c("Add user test", "Edit user admin"),
    details = c("User added", "User edited"),
    record = c(NA, NA),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_true(all(result$action_type %in% c("Users", NA)))
})
test_that("clean_redcap_log handles no-changes actions", {
  redcap_log <- data.frame(
    timestamp = "2024-01-15 10:30:00",
    username = "user1",
    action = "Enable external module test",
    details = "Module enabled",
    record = NA,
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_identical(result$action_type[1L], "No Changes")
})
test_that("clean_redcap_log sorts by timestamp descending", {
  redcap_log <- data.frame(
    timestamp = c(
      "2024-01-15 10:30:00",
      "2024-01-15 10:45:00",
      "2024-01-15 10:35:00"
    ),
    username = c("user1", "user2", "user3"),
    action = c("Update record 1", "Update record 2", "Update record 3"),
    details = c("Updated", "Updated", "Updated"),
    record = c("1", "2", "3"),
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  # Should be sorted by timestamp descending
  expect_identical(result$timestamp[1L], "2024-01-15 10:45:00")
  expect_identical(result$timestamp[2L], "2024-01-15 10:35:00")
  expect_identical(result$timestamp[3L], "2024-01-15 10:30:00")
})
test_that("clean_redcap_log removes record_id column", {
  redcap_log <- data.frame(
    timestamp = "2024-01-15 10:30:00",
    username = "user1",
    action = "Update record 123",
    details = "Updated",
    record = "123",
    record_id = NA,
    stringsAsFactors = FALSE
  )
  result <- clean_redcap_log(redcap_log)
  expect_false("record_id" %in% colnames(result))
})
# redcap_log_labeller (Internal)
test_that("redcap_log_labeller works!", {
})
# analyze_log (Internal)
test_that("analyze_log works!", {
  project_name <- "TEST_CLASSIC"
  project <- mock_test_project(project_name)$.internal
  id_col <- project$metadata$id_col
  interim_log <- data.frame(
    timestamp = as.character(Sys.time()),
    username = "u1231",
    action = "Create record (API) 99",
    details = NA,
    record = "99",
    action_type = "Create",
    stringsAsFactors = FALSE
  )
  expect_identical(analyze_log(interim_log, id_col)$length_updated_records, 1L)
  interim_log <- data.frame(
    timestamp = as.character(Sys.time()),
    username = "u1231",
    action = "Create record (API) 99",
    details = NA,
    record = "99",
    action_type = c("Create", "Update"),
    stringsAsFactors = FALSE
  )
  expect_identical(analyze_log(interim_log, id_col)$length_updated_records, 1L)
  interim_log <- data.frame(
    timestamp = as.character(Sys.time()),
    username = "u1231",
    action = "Create record (API) 99",
    details = NA,
    record = "99",
    action_type = "Delete",
    stringsAsFactors = FALSE
  )
  log_changes <- analyze_log(interim_log, id_col)
  expect_identical(log_changes$length_updated_records, 1L)
  expect_identical(log_changes$length_deleted_records, 1L)
  expect_identical(log_changes$updated_records, "99")
  expect_identical(log_changes$deleted_records, "99")
  expect_true(log_changes$refresh_data)
  expect_false(log_changes$refresh_metadata)
  interim_log <- data.frame(
    timestamp = as.character(Sys.time()),
    username = "u1231",
    action = "Changes to metadata",
    details = NA,
    record = NA,
    action_type = "Metadata Change Major",
    stringsAsFactors = FALSE
  )
  expect_true(analyze_log(interim_log, id_col)$refresh_metadata)
  interim_log <- data.frame(
    timestamp = as.character(Sys.time()),
    username = "u1231",
    action = "Changes to metadata",
    details = NA,
    record = NA,
    action_type = "Metadata Change Minor",
    stringsAsFactors = FALSE
  )
  expect_true(analyze_log(interim_log, id_col)$refresh_metadata)
})
# log_change_messages (Internal)
test_that("log_change_messages works!", {
  log_changes <- list(
    hard_reset = FALSE,
    refresh_metadata = FALSE,
    refresh_metadata_major = FALSE,
    refresh_metadata_minor = FALSE,
    refresh_users = FALSE,
    refresh_data = FALSE,
    deleted_records = NULL,
    updated_records = NULL,
    renamed_records = NULL,
    comment_records = NULL,
    length_deleted_records = 0L,
    length_updated_records = 0L,
    length_renamed_records = 0L,
    length_comment_records = 0L
  )
  expect_message(log_change_messages(log_changes), "Up to date")
  log_changes$refresh_metadata <- TRUE
  expect_message(log_change_messages(log_changes), "Full update triggered")
  log_changes$refresh_metadata <- FALSE
  log_changes$renamed_records <- "1c"
  log_changes$length_renamed_records <- 1L
  expect_message(log_change_messages(log_changes), "Full update triggered")
  log_changes$renamed_records <- NULL
  log_changes$length_renamed_records <- 0L
  log_changes$length_comment_records <- 1L
  log_changes$length_deleted_records <- 1L
  log_changes$length_updated_records <- 1L
  log_changes$comment_records <- "comment_record"
  log_changes$deleted_records <- "deleted_record"
  log_changes$updated_records <- "updated_record"
  expect_message(log_change_messages(log_changes), "Deleted: deleted")
  expect_message(log_change_messages(log_changes), "Updated: updated")
  expect_message(log_change_messages(log_changes), "Comments: comment")
})
# generate_comment_table (Internal)
test_that("generate_comment_table works!", {
  redcap_log <- TEST_CLASSIC$redcap$log[10L, ]
  time_offset <- seq(from = 100000L, to = 1000000L, by = 100000L)
  redcap_log_comments <- data.frame(
    timestamp = rep(Sys.time(), 10L) - time_offset,
    username = "commenter5",
    action = "Manage/Design",
    details = c(
      generate_comments("Edit", "1", "var_multi_dropdown", "some comment"),
      generate_comments("Add", "2", "var_branching", "different comment"),
      generate_comments("Delete", "2", "var_branching", "A comment"),
      generate_comments("Add", "2", "var_branching", "A comment"),
      generate_comments("Add", "3", "var_multi_dropdown", "some comment"),
      generate_comments("Add", "4", "var_branching", "a comment"),
      generate_comments("Edit", "1", "var_multi_dropdown", NULL),
      generate_comments("Add", "5", "var_multi_dropdown", "another comment"),
      generate_comments("Add", "1", "var_branching", "some comment"),
      generate_comments("Add", "1", "var_multi_dropdown", "some comment")
    ),
    record = c("1", "1", "2", "2", "3", "4", "1", "5", "1", "1"),
    action_type = "Comment",
    stringsAsFactors = FALSE
  )
  comment_table <- generate_comment_table(redcap_log = redcap_log_comments)
  expect_contains(comment_table$comment_type, c("Add", "Edit", "Delete"))
  expect_all_false(is.na(comment_table$comment_type))
  expect_all_false(is.na(comment_table$comment_field))
  expect_all_false(is.na(comment_table$comment_details[-7L]))
  expect_scalar_na(comment_table$comment_details[7L])
  expect_data_frame(comment_table, nrows = 10L)
  comment_table <- generate_comment_table(redcap_log = redcap_log_comments,
                                          only_most_recent = TRUE)
  comment_table
})
