Coverage for authentication\serializers\client.py: 91%
46 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 15:18 +0200
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 15:18 +0200
1"""
2Sérialiseurs pour l'inscription des clients.
4Ce module contient le(s) sérialiseur(s) permettant de gérer l'inscription
5des clients. Il inclut la validation des données d'entrée (email, mot de passe,
6nom, prénom, téléphone) et la création automatique du profil client associé à l'utilisateur.
7"""
9from rest_framework import serializers
10from django.contrib.auth.password_validation import validate_password
11from django.core.exceptions import ValidationError as DjangoValidationError
12from authentication.validators.emailValidator import EmailValidator
14from users.models.base_user import User
15from users.models.client import ClientProfile
18class ClientRegisterSerializer(serializers.ModelSerializer):
19 """
20 Sérialiseur pour l'inscription des clients.
22 Gère l'enregistrement complet d'un client, y compris :
23 - validation de l'email (unicité et format),
24 - validation du mot de passe (Django),
25 - validation du nom et prénom (≥2 caractères),
26 - validation du téléphone (≥10 chiffres),
27 - création de l'utilisateur et du profil client associé.
29 :field email: Adresse email unique du client.
30 :type email: str
31 :field password: Mot de passe sécurisé.
32 :type password: str
33 :field nom: Nom de famille.
34 :type nom: str
35 :field prenom: Prénom.
36 :type prenom: str
37 :field telephone: Numéro de téléphone.
38 :type telephone: str
39 """
41 email = serializers.EmailField(write_only=True, validators=[EmailValidator()])
42 nom = serializers.CharField(write_only=True)
43 prenom = serializers.CharField(write_only=True)
44 telephone = serializers.CharField(write_only=True)
45 password = serializers.CharField(write_only=True)
47 class Meta:
48 model = User
49 fields = ['email', 'password', 'nom', 'prenom', 'telephone']
51 def validate_email(self, value):
52 """
53 Vérifie que l'email n'est pas déjà utilisé.
55 :param value: Email à valider.
56 :type value: str
57 :raises serializers.ValidationError: Si l'email existe déjà.
58 :return: L'email validé.
59 :rtype: str
60 """
61 if User.objects.filter(email=value).exists():
62 raise serializers.ValidationError("Cet email est déjà utilisé.")
63 return value
65 def validate_password(self, value):
66 """
67 Applique la validation sécurisée de Django sur le mot de passe.
69 :param value: Mot de passe à valider.
70 :type value: str
71 :raises serializers.ValidationError: Si le mot de passe ne respecte pas les critères de sécurité.
72 :return: Le mot de passe validé.
73 :rtype: str
74 """
75 try:
76 validate_password(value, user=User(email=self.initial_data.get('email')))
77 except DjangoValidationError as e:
78 raise serializers.ValidationError(e.messages)
79 return value
81 def validate_nom(self, value):
82 """
83 Vérifie que le nom contient au moins 2 caractères.
85 :param value: Nom à valider.
86 :type value: str
87 :raises serializers.ValidationError: Si le nom est trop court.
88 :return: Nom validé.
89 :rtype: str
90 """
91 if len(value) < 2:
92 raise serializers.ValidationError("Le nom doit contenir au moins 2 caractères.")
93 return value
95 def validate_prenom(self, value):
96 """
97 Vérifie que le prénom contient au moins 2 caractères.
99 :param value: Prénom à valider.
100 :type value: str
101 :raises serializers.ValidationError: Si le prénom est trop court.
102 :return: Prénom validé.
103 :rtype: str
104 """
105 if len(value) < 2:
106 raise serializers.ValidationError("Le prénom doit contenir au moins 2 caractères.")
107 return value
109 def validate_telephone(self, value):
110 """
111 Vérifie que le numéro de téléphone contient au moins 10 chiffres et est numérique.
113 :param value: Numéro de téléphone à valider.
114 :type value: str
115 :raises serializers.ValidationError: Si le numéro est invalide.
116 :return: Numéro de téléphone validé.
117 :rtype: str
118 """
119 if not value.isdigit() or len(value) < 10:
120 raise serializers.ValidationError("Le numéro de téléphone doit contenir au moins 10 chiffres.")
121 return value
123 def create(self, validated_data):
124 """
125 Crée un utilisateur et son profil client associé.
127 :param validated_data: Données validées par le sérialiseur.
128 :type validated_data: dict
129 :return: Instance de l'utilisateur créé.
130 :rtype: User
131 """
132 nom = validated_data.pop('nom')
133 prenom = validated_data.pop('prenom')
134 telephone = validated_data.pop('telephone')
135 password = validated_data.pop('password')
136 email = validated_data['email']
138 user = User.objects.create_user(
139 email=email,
140 password=password,
141 role='client'
142 )
143 ClientProfile.objects.create(user=user, nom=nom, prenom=prenom, telephone=telephone)
144 return user