tests/testthat/test-aod.R

# Tests de aod_reference() et aod_individuel()

test_that("aod_reference() renvoie un data.table avec les bonnes colonnes", {
  ref <- aod_reference()
  expect_s3_class(ref, "data.table")
  expect_named(ref, c("aod", "caisse", "categorie", "dateNaissance", "dateApplication", "dateNaissanceEstimee"))
  expect_true(nrow(ref) > 0)
  # Chaque ligne doit avoir au moins dateNaissance ou dateApplication
  expect_true(all(!is.na(ref$dateNaissance) | !is.na(ref$dateApplication)))
})

test_that("aod_reference() snapshot", {
  expect_snapshot_value(as.data.frame(aod_reference()), style = "json2", cran = TRUE)
})

test_that("aod() pour les vieilles générations (avant les barèmes)", {
  # Gen 1910 : avant toutes les réformes
  expect_equal(aod(as.Date("1910-01-01")),                                           60)
  expect_equal(aod(as.Date("1910-01-01"), caisse = "SRE"),                            60)
  expect_equal(aod(as.Date("1910-01-01"), caisse = "SRE", categorie = "actif"),       55)
  expect_equal(aod(as.Date("1910-01-01"), caisse = "SRE", categorie = "superactif"),  50)
  expect_equal(aod(as.Date("1910-01-01"), caisse = "CNAVPL"),                         65)
  expect_equal(aod(as.Date("1910-01-01"), categorie = "inaptitude"),                  60)
  expect_equal(aod(as.Date("1910-01-01"), caisse = "MSA exploitant"),                 60)
})

test_that("aod_individuel() sans caisse ni catégorie = droit commun", {
  res <- aod_individuel(as.Date("1960-01-01"))
  expect_equal(res$aod, 62)
})

test_that("aod_individuel() avec caisse", {
  res <- aod_individuel(as.Date("1960-01-01"), caisse = "SRE", categorie = "actif")
  expect_equal(res$aod, 57)
})

test_that("aod_individuel() CNAVPL avec liquidation avant 2004 = 65", {
  res <- aod_individuel(as.Date("1939-01-01"), dateLiq = as.Date("1999-01-01"), caisse = "CNAVPL")
  expect_equal(res$aod, 65)
})

test_that("aod_individuel() CNAVPL avec liquidation après 2004 = droit commun", {
  res <- aod_individuel(as.Date("1960-01-01"), dateLiq = as.Date("2025-01-01"), caisse = "CNAVPL")
  expect_equal(res$aod, 62)
})

test_that("aod_individuel() CNAVPL sans dateLiq = calcul d'une pseudo-date de naissance", {
  dn <- as.Date(paste0(seq(1925, 1980, by = 5), "-01-01"))
  res <- aod(dn, caisse = "CNAVPL")
  # Générations qui liquident avant 2004-01 (cutoff ≈ 1939) : règle CNAVPL = 65
  expect_equal(res[1:3], rep(65, 3))
  # Générations qui liquident après 2004-01 : bascule sur le droit commun
  expect_equal(res[4:length(dn)], aod(dn[4:length(dn)]))
})

test_that("aod_individuel() dateLiq n'a aucun impact au droit commun", {
  datesLiq <- as.Date(c("1990-01-01", "2004-01-01", "2010-06-15", "2025-01-01", "2040-01-01"))
  sans <- aod_individuel(as.Date("1960-01-01"))
  avec <- aod_individuel(rep(as.Date("1960-01-01"), length(datesLiq)), dateLiq = datesLiq)
  expect_true(all(avec$aod == sans$aod))
})

test_that("aod() caisse FP sans catégorie = sédentaire par défaut", {
  # Regime special gen 1957 : sédentaire = 60.25, droit commun = 62
  expect_equal(
    aod(as.Date("1957-01-01"), caisse = "Regime special"),
    aod(as.Date("1957-01-01"), caisse = "Regime special", categorie = "sedentaire")
  )
  # SRE et CNRACL sédentaire = droit commun (pas de lignes spécifiques)
  expect_equal(
    aod(as.Date("1957-01-01"), caisse = "SRE"),
    aod(as.Date("1957-01-01"))
  )
  expect_equal(
    aod(as.Date("1957-01-01"), caisse = "CNRACL"),
    aod(as.Date("1957-01-01"))
  )
  # Passer categorie = "sedentaire" explicitement doit donner le même résultat
  expect_equal(
    aod(as.Date("1957-01-01"), caisse = "SRE", categorie = "sedentaire"),
    aod(as.Date("1957-01-01"), caisse = "SRE")
  )
  expect_equal(
    aod(as.Date("1957-01-01"), caisse = "CNRACL", categorie = "sedentaire"),
    aod(as.Date("1957-01-01"), caisse = "CNRACL")
  )
})

test_that("aod_individuel() gère les duplications dans les inputs", {
  # 100 fois le même individu
  res <- aod_individuel(
    rep(as.Date("1960-01-01"), 100),
    caisse = rep("CNAVPL", 100),
    dateLiq = rep(as.Date("2025-01-01"), 100)
  )
  expect_equal(nrow(res), 100)
  expect_true(all(res$aod == 62))

  # Mélange d'individus avec doublons
  dn <- rep(as.Date(c("1940-01-01", "1960-01-01")), each = 50)
  res2 <- aod_individuel(dn)
  expect_equal(nrow(res2), 100)
  expect_equal(res2$aod[1:50], rep(60, 50))
  expect_equal(res2$aod[51:100], rep(62, 50))
})

# --- Barème LFSS 2026 : suspension de la réforme Borne 2023 -------------------
#
# Source : https://www.cfdt-retraités.fr/47-Ouverture-des-droits-a-la-retraite
# (tableaux "AOD dès septembre 2026" pour sédentaire, actif, super-actif)
#
# Cf. aussi le commit Trajectoire 904a1a5e "Plfss2026dureesages" (Sigal,
# 2026-01-15) qui a porté ces valeurs dans `inst/extdata/trajectoire/ageDuree.csv`.

test_that("aod() — sédentaire FP, barème LFSS 2026 suspendu", {
  # Cohortes-clés au voisinage du décalage Borne -> suspendu
  expect_equal(aod(as.Date("1963-01-01"), caisse = "SRE", categorie = "sedentaire"), 62.75)
  expect_equal(aod(as.Date("1964-01-01"), caisse = "SRE", categorie = "sedentaire"), 62.75)
  expect_equal(aod(as.Date("1965-01-01"), caisse = "SRE", categorie = "sedentaire"), 62.75)
  expect_equal(aod(as.Date("1965-04-01"), caisse = "SRE", categorie = "sedentaire"), 63)
  expect_equal(aod(as.Date("1966-01-01"), caisse = "SRE", categorie = "sedentaire"), 63.25)
  expect_equal(aod(as.Date("1967-01-01"), caisse = "SRE", categorie = "sedentaire"), 63.5)
  expect_equal(aod(as.Date("1968-01-01"), caisse = "SRE", categorie = "sedentaire"), 63.75)
  expect_equal(aod(as.Date("1969-01-01"), caisse = "SRE", categorie = "sedentaire"), 64)
})

test_that("aod() — droit commun, barème LFSS 2026 suspendu", {
  # Mêmes valeurs que sédentaire FP par construction (fallback)
  expect_equal(aod(as.Date("1964-01-01")), 62.75)
  expect_equal(aod(as.Date("1965-04-01")), 63)
  expect_equal(aod(as.Date("1969-01-01")), 64)
})

test_that("aod() — actif FP, barème LFSS 2026 suspendu", {
  # Décalage +1 an vs Borne 2023 à partir de cohorte 1969
  expect_equal(aod(as.Date("1968-01-01"), caisse = "SRE", categorie = "actif"), 57.75)
  expect_equal(aod(as.Date("1969-01-01"), caisse = "SRE", categorie = "actif"), 57.75)
  expect_equal(aod(as.Date("1970-01-01"), caisse = "SRE", categorie = "actif"), 58)
  expect_equal(aod(as.Date("1971-01-01"), caisse = "SRE", categorie = "actif"), 58.25)
  expect_equal(aod(as.Date("1974-01-01"), caisse = "SRE", categorie = "actif"), 59)
})

test_that("aod() — super-actif FP, montée en charge Sarkozy 2010 + suspension LFSS 26", {
  # Montée en charge Sarkozy 2010 (cohortes 1961-1965) : barème calé sur
  # juris-cnracl, cf. commit 9bc0f23 "Correction des AOD des super-actifs
  # FP pour la période montée en charge de la réforme de 2010".
  expect_equal(aod(as.Date("1960-01-01"), caisse = "SRE", categorie = "superactif"), 50)
  expect_equal(aod(as.Date("1961-07-01"), caisse = "SRE", categorie = "superactif"), 50.33)
  expect_equal(aod(as.Date("1962-01-01"), caisse = "SRE", categorie = "superactif"), 50.75)
  expect_equal(aod(as.Date("1963-01-01"), caisse = "SRE", categorie = "superactif"), 51.17)
  expect_equal(aod(as.Date("1964-01-01"), caisse = "SRE", categorie = "superactif"), 51.58)
  expect_equal(aod(as.Date("1965-01-01"), caisse = "SRE", categorie = "superactif"), 52)
  expect_equal(aod(as.Date("1968-01-01"), caisse = "SRE", categorie = "superactif"), 52)
  expect_equal(aod(as.Date("1971-08-01"), caisse = "SRE", categorie = "superactif"), 52)

  # Réforme Borne 2023, avec suspension LFSS 26 : palier post-1973 décalé
  # d'1 an (53 → 1975-01 au lieu de 1974-01, etc.)
  expect_equal(aod(as.Date("1971-09-01"), caisse = "SRE", categorie = "superactif"), 52.25)
  expect_equal(aod(as.Date("1974-01-01"), caisse = "SRE", categorie = "superactif"), 52.75)
  expect_equal(aod(as.Date("1975-01-01"), caisse = "SRE", categorie = "superactif"), 53)
  expect_equal(aod(as.Date("1979-01-01"), caisse = "SRE", categorie = "superactif"), 54)
})

test_that("aod() — super-actif FP : SRE = CNRACL sur la montée en charge Sarkozy 2010", {
  # Le barème de la montée en charge Sarkozy 2010 est identique entre SRE
  # et CNRACL (cf. commit 9bc0f23, source juris-cnracl). Le Régime spécial
  # garde des valeurs distinctes, à valider — cf. issue d'aval.
  for (dn in as.Date(c("1961-07-01", "1962-01-01", "1963-01-01", "1965-01-01",
                       "1971-09-01", "1975-01-01", "1979-01-01"))) {
    expect_equal(
      aod(dn, caisse = "SRE",    categorie = "superactif"),
      aod(dn, caisse = "CNRACL", categorie = "superactif"),
      info = paste("cohorte", dn)
    )
  }
})

# --- AOD qui dépend de la date de liquidation (LFSS 2026 stricto sensu) ------
#
# La LFSS 2026 prévoit une suspension de la réforme Borne 2023 à partir du
# 09/2026 : un même individu peut tomber dans deux régimes différents selon
# qu'il liquide avant ou à partir du 1er septembre 2026.
#
# Exemple : sédentaire FP née 1964 (Borne AOD = 63, LFSS 26 = 62.75).
#   - Liq. avant 09/2026         → AOD = 63    (Borne en montée en charge)
#   - Liq. à partir de 09/2026   → AOD = 62.75 (LFSS 26 suspendu)
#
# Ces tests sont DÉSACTIVÉS : la modélisation à deux régimes n'existe pas
# encore dans legiretraite (`aod.csv` ne contient qu'un seul barème par
# cohorte, qui ici est le barème suspendu). Cf. issue legiretraite
# "révision AOD : double régime par date de liquidation".

test_that("aod() — même personne, deux régimes selon dateLiq (LFSS 2026)", {
  skip("Double-régime par dateLiq non encore modélisé — cf. issue legiretraite")
  dn <- as.Date("1964-01-01")
  expect_equal(aod(dn, dateLiq = as.Date("2026-08-15"), caisse = "SRE", categorie = "sedentaire"), 63)
  expect_equal(aod(dn, dateLiq = as.Date("2026-09-15"), caisse = "SRE", categorie = "sedentaire"), 62.75)
})

test_that("aod() — sédentaire FP née 1965 T1 vs T2 (double régime LFSS 2026)", {
  skip("Double-régime par dateLiq non encore modélisé — cf. issue legiretraite")
  t1 <- as.Date("1965-02-01")
  t2 <- as.Date("1965-05-01")
  expect_equal(aod(t1, dateLiq = as.Date("2027-01-01"), caisse = "SRE", categorie = "sedentaire"), 62.75)
  expect_equal(aod(t2, dateLiq = as.Date("2028-04-01"), caisse = "SRE", categorie = "sedentaire"), 63)
})

test_that("aod() — actif FP née 1970 T1 vs T2 (double régime LFSS 2026)", {
  skip("Double-régime par dateLiq non encore modélisé — cf. issue legiretraite")
  t1 <- as.Date("1970-02-01")
  t2 <- as.Date("1970-05-01")
  expect_equal(aod(t1, dateLiq = as.Date("2028-06-01"), caisse = "SRE", categorie = "actif"), 57.75)
  expect_equal(aod(t2, dateLiq = as.Date("2028-09-01"), caisse = "SRE", categorie = "actif"), 58)
})

test_that("aod() — super-actif FP née 1975 T1 vs T2 (double régime LFSS 2026)", {
  skip("Double-régime par dateLiq non encore modélisé — cf. issue legiretraite")
  t1 <- as.Date("1975-02-01")
  t2 <- as.Date("1975-05-01")
  expect_equal(aod(t1, dateLiq = as.Date("2028-06-01"), caisse = "SRE", categorie = "superactif"), 52.75)
  expect_equal(aod(t2, dateLiq = as.Date("2028-09-01"), caisse = "SRE", categorie = "superactif"), 53)
})

# --- Régimes spéciaux individuels : alias vers "Regime special" -------------
#
# Les caisses individuelles des régimes spéciaux (SNCF, ENIM, RATP, etc.) ne
# disposent pas de barème AOD propre dans legiretraite. Le lookup les re-route
# automatiquement vers le pool "Regime special".

test_that("aod() — caisses régimes spéciaux individuels = pool Regime special", {
  dates <- as.Date(c("1942-01-01", "1955-01-01", "1962-01-01", "1965-04-01",
                     "1968-01-01", "1972-01-01"))
  for (caisse_indiv in caissesRegimesSpeciauxIndividuels) {
    for (categ in c("sedentaire", "actif", "superactif")) {
      expect_equal(
        aod(dates, caisse = caisse_indiv,        categorie = categ),
        aod(dates, caisse = "Regime special",    categorie = categ),
        info = paste(caisse_indiv, "/", categ)
      )
    }
    # Sans catégorie : caisse FP -> sédentaire par défaut, devrait aussi marcher
    expect_equal(
      aod(dates, caisse = caisse_indiv),
      aod(dates, caisse = "Regime special"),
      info = paste(caisse_indiv, "/ (défaut)")
    )
  }
})

test_that("aod_individuel() snapshot sur une grille de cas", {
  grille <- CJ(
    dateNaissance = as.Date(c("1940-01-01", "1955-01-01", "1960-01-01", "1970-01-01")),
    caisse = c(NA_character_, "SRE", "CNRACL", "Regime special", "MSA exploitant"),
    categorie = c(NA_character_, "actif", "sedentaire", "superactif", "inaptitude")
  )
  grille <- grille[
    (is.na(caisse) & categorie %in% c(NA_character_, "inaptitude")) |
    (caisse %in% c("SRE", "CNRACL", "Regime special") & categorie %in% c("actif", "sedentaire", "superactif")) |
    (caisse == "MSA exploitant" & is.na(categorie))
  ]
  res <- aod_individuel(
    dateNaissance = grille$dateNaissance,
    caisse        = grille$caisse,
    categorie     = grille$categorie
  )
  expect_snapshot_value(as.data.frame(res), style = "json2", cran = TRUE)
})

Try the legiretraite package in your browser

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

legiretraite documentation built on Oct. 7, 2026, 5:09 p.m.