# Mock data for testing create_sample_announcement_data <- function() { data.frame( StartDateTime = as.POSIXct(c("2024-01-15 08:00:00", "2024-01-20 10:00:00")), EndDateTime = as.POSIXct(c("2024-01-15 18:00:00", "2024-01-20 20:00:00")), StartLatitude = c("15°30'S", "16°00'S"), EndLatitude = c("15°45'S", "16°15'S"), StartLongitude = c("75°30'W", "76°00'W"), EndLongitude = c("75°45'W", "76°15'W"), StartNauticalMiles = c(5, 10), EndNauticalMiles = c(15, 25), file_name = c("announcement1.pdf", "announcement2.pdf"), announcement = c("Announcement 1", "Announcement 2"), stringsAsFactors = FALSE ) } # Tests for fetch_fishing_announcements() test_that("fetch_fishing_announcements validates parameters", { # Test that function exists expect_true(exists("fetch_fishing_announcements")) # Test basic parameter validation without actually making HTTP calls start_date <- "01/01/2024" end_date <- "31/01/2024" expect_error( fetch_fishing_announcements( start_date = start_date, end_date = end_date, batch_size = -1 ), regexp = ".*" ) }) test_that("fetch_fishing_announcements handles required parameters", { # Test missing required parameters expect_error( fetch_fishing_announcements(), regexp = ".*" ) }) # Tests for extract_pdf_data() test_that("extract_pdf_data handles empty input", { expect_error( result <- extract_pdf_data(character(0)), "'pdf_sources' is required and cannot be NULL or empty." ) }) test_that("extract_pdf_data errors when no files exist", { non_existent_files <- c("nonexistent1.pdf", "nonexistent2.pdf") expect_error( suppressWarnings( extract_pdf_data(non_existent_files, verbose = FALSE) ), "Could not access any of the specified files" ) }) test_that("extract_pdf_data handles invalid input types", { expect_error( extract_pdf_data(123), "'pdf_sources' must be a character vector" ) expect_error( extract_pdf_data(), "'pdf_sources' is required and cannot be NULL or empty." ) }) test_that("extract_pdf_data errors when all URLs fail", { test_urls <- c( "http://example.com/file1.pdf", "https://example.com/file2.pdf", "ftp://example.com/file3.pdf" ) expect_error( suppressWarnings( extract_pdf_data(test_urls, max_retries = 1, verbose = FALSE) ), regexp = "Could not access" ) }) # Tests for format_extracted_data() test_that("format_extracted_data works correctly", { sample_data <- create_sample_announcement_data() result <- format_extracted_data( data = sample_data, convert_coordinates = TRUE ) expect_s3_class(result, "data.frame") expect_equal(nrow(result), nrow(sample_data)) # Check that datetime columns are properly formatted expect_s3_class(result$StartDateTime, "POSIXct") expect_s3_class(result$EndDateTime, "POSIXct") }) test_that("format_extracted_data handles date filtering", { sample_data <- create_sample_announcement_data() # Filter to only include first announcement result <- format_extracted_data( data = sample_data, min_date = "2024-01-01", max_date = "2024-01-16" ) expect_s3_class(result, "data.frame") expect_equal(nrow(result), 1) expect_equal(result$file_name[1], "announcement1.pdf") }) test_that("format_extracted_data handles coordinate conversion", { skip_if_not_installed("stringr") sample_data <- create_sample_announcement_data() result <- format_extracted_data( data = sample_data, convert_coordinates = TRUE ) coord_decimal_cols <- c("StartLatitude_decimal", "EndLatitude_decimal", "StartLongitude_decimal", "EndLongitude_decimal") expect_s3_class(result, "data.frame") }) test_that("format_extracted_data validates required structure", { invalid_data <- data.frame( invalid_column = c(1, 2, 3) ) expect_error( format_extracted_data(invalid_data), "Data does not have expected structure" ) }) test_that("format_extracted_data handles empty result after filtering", { sample_data <- create_sample_announcement_data() expect_warning( result <- format_extracted_data( data = sample_data, min_date = "2025-01-01", max_date = "2025-01-31" ), "No data meets the filtering criteria" ) expect_equal(nrow(result), 0) }) test_that("format_extracted_data handles different date input formats", { sample_data <- create_sample_announcement_data() # Test with Date objects min_date_obj <- as.Date("2024-01-01") max_date_obj <- as.Date("2024-01-16") result <- format_extracted_data( data = sample_data, min_date = min_date_obj, max_date = max_date_obj ) expect_s3_class(result, "data.frame") expect_equal(nrow(result), 1) }) test_that("format_extracted_data handles numeric conversion", { # Create data with text numeric columns sample_data <- create_sample_announcement_data() sample_data$StartNauticalMiles <- c("5.5", "10.2") sample_data$EndNauticalMiles <- c("15.7", "25.3") result <- format_extracted_data(sample_data) expect_type(result$StartNauticalMiles, "double") expect_type(result$EndNauticalMiles, "double") expect_equal(result$StartNauticalMiles[1], 5.5) }) test_that("format_extracted_data handles NA values", { sample_data <- create_sample_announcement_data() sample_data$StartNauticalMiles[1] <- NA sample_data$StartLatitude[2] <- NA result <- format_extracted_data(sample_data) expect_s3_class(result, "data.frame") expect_equal(nrow(result), 2) expect_true(is.na(result$StartNauticalMiles[1])) }) # Tests for coordinate conversion in announcements test_that("announcement coordinate conversion works", { # Test DMS coordinate conversion dms_coords <- c("15°30'25\"S", "75°45'30\"W") # This would use the dms_to_decimal function decimal_coords <- dms_to_decimal(dms_coords) expect_type(decimal_coords, "double") expect_length(decimal_coords, 2) expect_true(all(decimal_coords < 0)) }) # Tests for date parsing in announcements test_that("announcement date parsing works", { # Test various date formats that might appear in announcements date_strings <- c( "2024-01-15 08:00:00", "15/01/2024 08:00", "2024-01-15T08:00:00Z" ) for (date_str in date_strings) { result <- convert_to_date(date_str, output_type = "datetime") expect_s3_class(result, "POSIXct") } }) # Helper function tests test_that("announcement helper functions exist", { # Test that required helper functions exist for announcements helper_functions <- c( "check_required_packages", "get_main_page", "extract_cookies", "extract_token", "create_download_dir", "fetch_announcements_batch", "generate_download_url", "download_file", "is_date_in_range", "process_pdf_text", "safe_numeric_conversion" ) for (func in helper_functions) { expect_true(exists(func), info = paste("Function", func, "should exist")) } }) # Test parameter validation for helper functions test_that("safe_numeric_conversion works correctly", { # Test valid numeric strings valid_nums <- c("123", "45.67", "0", "-12.34") result <- safe_numeric_conversion(valid_nums, "test_column") expect_type(result, "double") expect_equal(result, c(123, 45.67, 0, -12.34)) # Test invalid strings invalid_nums <- c("abc", "12.34.56", "", NA) expect_warning( result <- safe_numeric_conversion(invalid_nums, "test_column"), "could not be converted to numeric and were set to NA" ) expect_true(any(is.na(result))) }) test_that("is_date_in_range works correctly", { test_date <- "2024-01-15" start_date <- "2024-01-01" end_date <- "2024-01-31" # This tests the date range checking function result <- is_date_in_range(test_date, start_date, end_date) expect_type(result, "logical") expect_true(result) # Test date outside range outside_date <- "2024-02-15" result_outside <- is_date_in_range(outside_date, start_date, end_date) expect_false(result_outside) }) # Integration test test_that("announcement workflow integration", { # Test that the main functions can work together sample_data <- create_sample_announcement_data() # Format the data formatted_data <- format_extracted_data(sample_data) # Check that workflow produces valid output expect_s3_class(formatted_data, "data.frame") expect_true(nrow(formatted_data) > 0) expect_true("StartDateTime" %in% names(formatted_data)) expect_true("EndDateTime" %in% names(formatted_data)) # Test coordinate conversion if implemented if ("StartLatitude_decimal" %in% names(formatted_data)) { expect_type(formatted_data$StartLatitude_decimal, "double") } }) # Test error handling in announcements test_that("announcement functions handle errors gracefully", { # Test PDF extraction with invalid input expect_error( extract_pdf_data(NULL), "'pdf_sources' is required and cannot be NULL or empty." ) # Test format_extracted_data with invalid structure expect_error( format_extracted_data(list(invalid = "structure")), regexp = ".*" ) }) # Test announcement data validation test_that("announcement data validation works", { sample_data <- create_sample_announcement_data() # Check required columns exist required_cols <- c("StartDateTime", "EndDateTime", "StartLatitude", "EndLatitude") expect_true(all(required_cols %in% names(sample_data))) # Check data types expect_s3_class(sample_data$StartDateTime, "POSIXct") expect_s3_class(sample_data$EndDateTime, "POSIXct") expect_type(sample_data$StartLatitude, "character") expect_type(sample_data$EndLatitude, "character") })