Tests et gestion des dates et heures avec Ruby on Rails

Comment gérer l'affichage d'un contenu Web, texte ou image, en fonction de la date et de l'heure ? Proposition d'une marche à suivre au sein du framework Rails.

Dans chaque application Internet de nombreux traitements sont dépendants de la date ou de l'heure :

 Affichage d'une offre promotionnelle durant une période donnée,
 Documents visibles uniquement à partir de la date de publication,
 Envoi de mailing seulement aux utilisateurs inscrits depuis une date données,
 affichage d'un logo différent en fonction de la saison, du mois, de l'heure de la journée.

Cette liste n'est pas exhaustive mais je suis sûr que vous avez également déjà rencontré cette situation. Il n'est pas difficile de gérer ces cas avec Ruby On Rails, une méthode spécifique (ou un named_scope) dans votre modèle avec les bonnes conditions et le tour est joué pour tout ce qui est relatif à la base de données. Un petit helper est suffisant pour afficher les différents logos en fonction de la date, de l'heure.

Mais quand est-il des tests ? En effet, admettons que je veuille afficher un message de bienvenue différent en fonction de l'heure à mes visiteurs. Pour celà je vais utiliser un helper "message_bienvenue" que je placerai dans mon fichier application_helper.rb.

Mais commençons par écrire des tests unitaires que nous placerons dans le fichier application_helper_test.rb afin de vérifier que l'on obtienne bien ce que l'on souhaite :

 def test_message_bienvenue_should_return_
bonjour_if_hour_before_18
 assert_equal("Bonjour", message_bienvenue)
end
 
def test_message_bienvenue_should_return_
bonsoir_if_hour_after_18
 assert_equal("Bonsoir", message_bienvenue)
end

Vous comprenez tout de suite que mes tests ne peuvent pas en l'état réussir tous les deux puisqu'à une heure donnée, soit le premier test réussira, soit le second ! Nous devons donc trouver un moyen de faire croire à Ruby que le test est exécuté à l'heure qui nous intéresse. Nous allons pour celà utiliser un helper : Le fichier time_helper.rb est disponible ici et je vous conseille de le placer à la racine de votre dossier de test, au même niveau que le fichier test_helper.rb.

Grâce à cet helper que l'on inclus en ajoutant :

  require File.dirname(__FILE__) + '/../time_helper' 


Au début du fichier de test, nous pouvons désormais améliorer nos tests grâce à la fonction pretend_now_is :

 

def test_message_bienvenue_should_return_
bonjour_if_hour_before_18
 pretend_now_is(Time.local(2008, 12, 23, 14, 05)) do
   assert_equal("Bonjour", message_bienvenue)
 end
end
 
def test_message_bienvenue_should_return_
bonsoir_if_hour_after_18
 pretend_now_is(Time.local(2008, 12, 23, 19, 23)) do
   assert_equal("Bonsoir", message_bienvenue)
 end
end

Grâce à cette fonction pretend_now_is, lorsque votre test est exécuté, la date et l'heure sont fixées à la date et l'heure que vous passez en paramètres. Nos tests ne passent toujours pas et c'est logique puisque nous n'avons pas écrit le helper message_bienvenue.

Nous allons donc écrire le code minimum pour faire passer nos tests :

 def message_bienvenue
 if Time.now.hour < 18
   "Bonjour"
 else
   "Bonsoir"
 end
end

Cette fois les tests unitaires passent, nous avons donc atteint notre objectif !

Ce contenu a été réalisé par le blog accolade.ch (Raphaël Emourgeon) sous licence Creative Commons.