source(testthat::test_path("..", "..", "R", "rain_db.R")) test_that("normalise_rainfall_data converts API payload into unified metric rows", { raw_data <- data.frame( POSTE = c("1001", "1001"), DATE = c(202401020000, 202401020006), RR6 = c(0, 1.5), Nom_usuel = c("Station A", "Station A"), stringsAsFactors = FALSE ) cache_rows <- normalise_rainfall_data( raw_data = raw_data, location_id = "vignasses", fetched_at = as.POSIXct("2026-04-08 09:00:00", tz = "UTC") ) expect_identical( names(cache_rows), c( "location_id", "station_id", "station_name", "observed_at", "observed_day", "metric_id", "metric_label", "unit", "source_name", "value_num", "fetched_at" ) ) expect_equal(cache_rows$metric_id[1], "rain_6m") expect_equal(cache_rows$observed_at[2], "2024-01-02T00:06:00Z") expect_equal(cache_rows$fetched_at[1], "2026-04-08T09:00:00Z") }) test_that("normalise_observation_package_data extracts temperature and other metrics", { raw_data <- data.frame( geo_id_insee = c("1001", "1001"), validity_time = c("2026-04-08T09:24:00Z", "2026-04-08T09:30:00Z"), t = c(293.15, 294.15), td = c(289.15, 290.15), u = c(40, 42), ff = c(1.5, 2.0), fxi10 = c(3.5, 4.0), pres = c(101325, 101425), pmer = c(101525, 101625), stringsAsFactors = FALSE ) cache_rows <- normalise_observation_package_data( raw_data = raw_data, location_id = "vignasses", station_name = "Station A", fetched_at = as.POSIXct("2026-04-08 10:00:00", tz = "UTC") ) expect_true(all(c( "air_temperature", "dew_point", "humidity", "wind_speed", "wind_gust", "station_pressure", "sea_level_pressure" ) %in% unique(cache_rows$metric_id))) expect_equal(cache_rows$value_num[cache_rows$metric_id == "air_temperature"][1], 20) expect_equal(cache_rows$value_num[cache_rows$metric_id == "station_pressure"][1], 1013.2) }) test_that("SQLite cache upserts and queries multiple metrics from one dataset", { skip_if_not(nzchar(Sys.which("sqlite3")), "sqlite3 is required for cache tests.") db_path <- tempfile(fileext = ".sqlite") on.exit(unlink(c(db_path, paste0(db_path, c("-shm", "-wal")))), add = TRUE) ensure_weather_db(db_path) rain_rows <- normalise_rainfall_data( raw_data = data.frame( POSTE = c("1001", "1001"), DATE = c(202401020000, 202401020006), RR6 = c(1.25, 0.5), Nom_usuel = c("Station A", "Station A"), stringsAsFactors = FALSE ), location_id = "vignasses", fetched_at = as.POSIXct("2026-04-08 09:00:00", tz = "UTC") ) obs_rows <- normalise_observation_package_data( raw_data = data.frame( geo_id_insee = c("1001", "1001"), validity_time = c("2024-01-02T00:00:00Z", "2024-01-02T06:00:00Z"), t = c(293.15, 295.15), u = c(40, 44), ff = c(1.5, 2.5), pres = c(101325, 101225), stringsAsFactors = FALSE ), location_id = "vignasses", station_name = "Station A", fetched_at = as.POSIXct("2026-04-08 09:00:00", tz = "UTC") ) expect_equal(upsert_weather_measurements(rain_rows, db_path), 2) expect_true(upsert_weather_measurements(obs_rows, db_path) >= 6) updated_rain <- rain_rows[1, , drop = FALSE] updated_rain$value_num <- 2 expect_true(upsert_rainfall_observations(updated_rain, db_path) >= 1) rain_raw <- query_cached_rainfall( location_id = "vignasses", start_date = "2024-01-02", end_date = "2024-01-02", aggregate = "raw", db_path = db_path ) rain_daily <- query_cached_rainfall( location_id = "vignasses", start_date = "2024-01-02", end_date = "2024-01-02", aggregate = "daily", db_path = db_path ) temperature_raw <- query_cached_metric( location_id = "vignasses", metric_id = "air_temperature", start_date = "2024-01-02", end_date = "2024-01-02", aggregate = "raw", db_path = db_path ) temperature_daily <- query_cached_metric( location_id = "vignasses", metric_id = "air_temperature", start_date = "2024-01-02", end_date = "2024-01-02", aggregate = "daily", db_path = db_path ) latest_temperature <- query_latest_metric_values( location_id = "vignasses", metric_id = "air_temperature", db_path = db_path ) expect_equal(nrow(rain_raw), 2) expect_equal(rain_raw$rain_mm[1], 2) expect_equal(rain_daily$rain_mm[1], 2.5) expect_equal(nrow(temperature_raw), 2) expect_equal(temperature_daily$value_num[1], 21) expect_equal(latest_temperature$value_num[1], 22) expect_equal( as.character(get_sync_start_date("vignasses", db_path, end_date = as.Date("2024-01-10"))), "2023-12-21" ) expect_equal( as.character(get_sync_start_date("vignasses", db_path, end_date = as.Date("2024-01-01"))), "2023-12-12" ) }) test_that("sync ranges are chunked predictably", { ranges <- split_sync_ranges( start_date = as.Date("2024-01-01"), end_date = as.Date("2024-05-15"), chunk_days = 60L ) expect_equal(nrow(ranges), 3) expect_equal(as.character(ranges$start_date[1]), "2024-01-01") expect_equal(as.character(ranges$end_date[3]), "2024-05-15") }) test_that("weekly and monthly rainfall aggregates collapse long windows", { skip_if_not(nzchar(Sys.which("sqlite3")), "sqlite3 is required for cache tests.") db_path <- tempfile(fileext = ".sqlite") on.exit(unlink(c(db_path, paste0(db_path, c("-shm", "-wal")))), add = TRUE) ensure_weather_db(db_path) rain_rows <- normalise_rainfall_data( raw_data = data.frame( POSTE = c("1001", "1001", "1001"), DATE = c(202401020000, 202401090000, 202402010000), RR6 = c(1, 2, 3), Nom_usuel = c("Station A", "Station A", "Station A"), stringsAsFactors = FALSE ), location_id = "vignasses", fetched_at = as.POSIXct("2026-04-08 09:00:00", tz = "UTC") ) expect_equal(upsert_weather_measurements(rain_rows, db_path), 3) weekly_rain <- query_cached_rainfall( location_id = "vignasses", start_date = "2024-01-01", end_date = "2024-02-01", aggregate = "weekly", db_path = db_path ) monthly_rain <- query_cached_rainfall( location_id = "vignasses", start_date = "2024-01-01", end_date = "2024-02-01", aggregate = "monthly", db_path = db_path ) expect_equal(as.character(weekly_rain$observed_day), c("2024-01-01", "2024-01-08", "2024-01-29")) expect_equal(weekly_rain$rain_mm, c(1, 2, 3)) expect_equal(as.character(monthly_rain$observed_day), c("2024-01-01", "2024-02-01")) expect_equal(monthly_rain$rain_mm, c(3, 3)) }) test_that("rain plot labels reflect grouped totals", { expect_equal(get_metric_plot_y_label("rain_6m", "raw"), "Rain (mm / 6 min)") expect_equal(get_metric_plot_y_label("rain_6m", "daily"), "Daily rain total (mm)") expect_equal(get_metric_plot_y_label("rain_6m", "weekly"), "Weekly rain total (mm)") expect_equal(get_metric_plot_y_label("rain_6m", "monthly"), "Monthly rain total (mm)") expect_equal(get_metric_plot_y_label("air_temperature", "weekly"), "Temperature (C)") })