diff --git a/R/suggestions.R b/R/suggestions.R index 7ce4487..b0299fa 100644 --- a/R/suggestions.R +++ b/R/suggestions.R @@ -300,14 +300,14 @@ #' result. #' @return Data frame with columns `recipe_id` (character) and `year` #' (integer). Returns an empty data frame (`recipe_id = character(0)`, -#' `year = integer(0)`) when `gap_years` is empty, so callers can safely -#' reference `$recipe_id`. +#' `year = integer(0)`) when `gap_years` or `candidates` is empty, so +#' callers can safely reference `$recipe_id`. #' @noRd .query_covered_years <- function(con, candidates, cohort, gap_years) { - if (length(gap_years) == 0L) { + if (length(gap_years) == 0L || length(candidates) == 0L) { return(data.frame(recipe_id = character(0), year = integer(0))) } - DBI::dbGetQuery(con, sprintf( + res <- DBI::dbGetQuery(con, sprintf( "SELECT DISTINCT r.recipe_id, l.year FROM long l JOIN harmonization_recipes r @@ -322,6 +322,8 @@ .sql_lit_chr(candidates), .cohort_sql(cohort, "l.canonical_govid"), paste(gap_years, collapse = ",") )) + res$year <- as.integer(res$year) + res } #' Query recipe metadata: labels and year spans for a set of candidate diff --git a/tests/testthat/test-recipes.R b/tests/testthat/test-recipes.R index fcb950b..18f3064 100644 --- a/tests/testthat/test-recipes.R +++ b/tests/testthat/test-recipes.R @@ -392,6 +392,26 @@ test_that("I1 + #34: cog_revenue never suggests expenditure-only recipes", { expect_false("corrections_combined" %in% ids) }) +test_that(".query_candidate_recipes() scopes candidates by category_type (#34)", { + # Direct assertion on the mechanism the two tests above exercise + # end-to-end: corrections_combined's own components (E04/E05) are + # category_type = 'expenditure' in summary_categories, so an + # expenditure-flavored flow_prefixes call must surface it and a + # revenue-flavored one must not. This queries only summary_categories/ + # harmonization_recipes (no government data), so it runs against the + # bundled fixture with no skip_if_no_corpus() needed. + con <- uscogdata:::.ensure_session() + + expenditure <- uscogdata:::.query_candidate_recipes( + con, category = "Corrections", flow_prefixes = c("E", "F", "G")) + expect_true("corrections_combined" %in% expenditure) + + revenue <- uscogdata:::.query_candidate_recipes( + con, category = "Corrections", + flow_prefixes = c("T", "A", "U", "B", "C", "D")) + expect_false("corrections_combined" %in% revenue) +}) + test_that("uscogdata#9: no partial-coverage fire in a modern year", { skip_if_no_corpus() r <- cog_spending("061037123085", years = 2019L, category = "Public Welfare")