- Lien d'inscription protégé par un jeton (FormTemplate.access_token, /inscription/<token>), avec régénération depuis l'écran de configuration. - Reçus fiscaux mécénat (cerfa 11580*05) : un PDF par bénévole ayant payé en mécénat, donateur/montant (chiffres et toutes lettres en français, app/mecenat/number_words.py)/date complétés par-dessus le modèle officiel. - Jeu de démonstration : bénévoles avec cotisation classique ou mécénat payée. - Infobulles (HelpTip et détail de cellule de la grille des besoins) repositionnées en position: fixed via JS, bornées à l'écran. - Revue de sécurité : logo des emails en pièce jointe inline au lieu d'une URL (fuyait le jeton d'inscription), sujet retiré du log de remise des emails (pouvait porter un nom de bénévole), photo du formulaire public revalidée par décodage réel avant stockage, export Excel protégé contre l'injection de formule, sondage du statut de paiement limité en fréquence, pyjwt mis à jour. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
from app.mecenat.number_words import amount_in_words
|
|
|
|
|
|
def test_zero_centimes_only_euros():
|
|
assert amount_in_words(15.0) == "Quinze euros"
|
|
|
|
|
|
def test_singular_euro_has_no_s():
|
|
assert amount_in_words(1.0) == "Un euro"
|
|
|
|
|
|
def test_et_un_forms():
|
|
assert amount_in_words(21.0) == "Vingt et un euros"
|
|
assert amount_in_words(31.0) == "Trente et un euros"
|
|
assert amount_in_words(61.0) == "Soixante et un euros"
|
|
|
|
|
|
def test_seventies_irregular_et_onze():
|
|
assert amount_in_words(70.0) == "Soixante-dix euros"
|
|
assert amount_in_words(71.0) == "Soixante et onze euros"
|
|
assert amount_in_words(72.0) == "Soixante-douze euros"
|
|
assert amount_in_words(79.0) == "Soixante-dix-neuf euros"
|
|
|
|
|
|
def test_eighties_no_et_ever():
|
|
assert amount_in_words(80.0) == "Quatre-vingts euros"
|
|
assert amount_in_words(81.0) == "Quatre-vingt-un euros"
|
|
assert amount_in_words(91.0) == "Quatre-vingt-onze euros"
|
|
assert amount_in_words(99.0) == "Quatre-vingt-dix-neuf euros"
|
|
|
|
|
|
def test_hundreds_agreement():
|
|
assert amount_in_words(100.0) == "Cent euros"
|
|
assert amount_in_words(101.0) == "Cent un euros"
|
|
assert amount_in_words(200.0) == "Deux cents euros"
|
|
assert amount_in_words(201.0) == "Deux cent un euros"
|
|
|
|
|
|
def test_thousands_are_invariable():
|
|
assert amount_in_words(1000.0) == "Mille euros"
|
|
assert amount_in_words(2000.0) == "Deux mille euros"
|
|
assert amount_in_words(1234.0) == "Mille deux cent trente-quatre euros"
|
|
|
|
|
|
def test_cents_only_when_no_euros():
|
|
assert amount_in_words(0.5) == "Cinquante centimes"
|
|
assert amount_in_words(0.01) == "Un centime"
|
|
|
|
|
|
def test_euros_and_cents_joined_with_et():
|
|
assert amount_in_words(1234.56) == (
|
|
"Mille deux cent trente-quatre euros et cinquante-six centimes"
|
|
)
|
|
assert amount_in_words(1.01) == "Un euro et un centime"
|
|
|
|
|
|
def test_rounds_to_the_nearest_cent():
|
|
# Erreurs de flottant (ex. 0.1 + 0.2) ne doivent jamais se voir.
|
|
assert amount_in_words(19.999999) == "Vingt euros"
|