Validation de l’email d’inscription ajoutée
All checks were successful
Dotnet build and test / build (pull_request) Successful in 4m53s

Vvalidation au point le plus sûr : le modèle de formulaire, avec un garde-fou côté contrôleur pour normaliser la valeur avant création du compte.

* Ajout de [EmailAddress] dans RegisterModel.cs
* Nettoyage de model.Email avec Trim() avant le ModelState.IsValid dans AccountController.cs
* Ajout d’un test de régression dans EMailling.cs

Additionnellement, le job de test est corrigé pour laisser vivre le test en plateforme Android, hors CI
This commit is contained in:
Paul Schneider 2026-08-29 16:23:58 +01:00
commit 6a6cc3a967
Signed by: notazof
GPG key ID: 1DD5D838E5343B06
6 changed files with 37 additions and 6 deletions

View file

@ -44,4 +44,8 @@ jobs:
- name: Test - name: Test
run: | run: |
echo "🚀 Lancement des tests..." echo "🚀 Lancement des tests..."
cd /src/_src && dotnet test --verbosity normal && echo "✅ Success !" || echo "❌ Fail ($?)!" cd /src/_src && dotnet test \
--verbosity normal \
--filter="Category!=Platform-Android" \
--logger "xunit;LogFileName=test-results.xml" \
&& echo "✅ Success !" || echo "❌ Fail ($?)!"

View file

@ -26,7 +26,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Test - name: Test
run: dotnet test --no-build --verbosity normal run: dotnet test --no-build --verbosity normal --filter="Category!=Platform-Android"
# 4. Build et Push de l'image de production finale # 4. Build et Push de l'image de production finale
- name: Build and push production image - name: Build and push production image
uses: docker/build-push-action@v7 uses: docker/build-push-action@v7

View file

@ -12,6 +12,7 @@ namespace PostIt.Tests;
/// Skip conditions: the package is not installed on the connected device, /// Skip conditions: the package is not installed on the connected device,
/// or no device is connected via adb. /// or no device is connected via adb.
/// </summary> /// </summary>
[Trait("Category", "Platform-Android")]
public class AndroidAppLaunchTests public class AndroidAppLaunchTests
{ {
private const string PackageName = "fr.pschneider.postit"; private const string PackageName = "fr.pschneider.postit";
@ -23,8 +24,8 @@ public class AndroidAppLaunchTests
_output = output; _output = output;
} }
// https://twosixtech.com/blog/integrating-docker-and-adb/ // TODO https://twosixtech.com/blog/integrating-docker-and-adb/
// FIXME ala hosted shared resource adb server - [Fact] [Fact]
public void PostIt_starts_and_draws_a_first_frame_on_the_emulator() public void PostIt_starts_and_draws_a_first_frame_on_the_emulator()
{ {
if (!IsPackageInstalledOnAnyDevice()) if (!IsPackageInstalledOnAnyDevice())

View file

@ -12,8 +12,8 @@ namespace Yavsc.ViewModels.Account
public string UserName { get; set; } public string UserName { get; set; }
[Required()] [Required()]
[StringLength( maximumLength:102, MinimumLength = 5)] [StringLength(maximumLength: 102, MinimumLength = 5)]
// [EmailAddress] [EmailAddress(ErrorMessage = "L'adresse e-mail n'est pas valide.")]
[Display(Name = "Email", Description = "E-Mail")] [Display(Name = "Email", Description = "E-Mail")]
public string Email { get; set; } public string Email { get; set; }

View file

@ -1,8 +1,10 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Yavsc.Interface; using Yavsc.Interface;
using Yavsc.Interfaces; using Yavsc.Interfaces;
using Yavsc.Org.Tests.Fakes; using Yavsc.Org.Tests.Fakes;
using Yavsc.ViewModels.Account;
namespace Yavsc.Org.Tests namespace Yavsc.Org.Tests
{ {
@ -56,5 +58,27 @@ namespace Yavsc.Org.Tests
Assert.Equal(_serverFixture.SiteSettings.Owner.EMail, client.LastSentMessage?.To.Mailboxes.First().Address); Assert.Equal(_serverFixture.SiteSettings.Owner.EMail, client.LastSentMessage?.To.Mailboxes.First().Address);
} }
[Fact]
public void RegisterModel_rejects_invalid_email_format()
{
var model = new RegisterModel
{
UserName = "alice",
Email = "this is not an email",
Password = "Password123!",
ConfirmPassword = "Password123!"
};
var results = new List<ValidationResult>();
var valid = Validator.TryValidateObject(
model,
new ValidationContext(model),
results,
validateAllProperties: true);
Assert.False(valid);
Assert.Contains(results, r => r.MemberNames.Contains(nameof(RegisterModel.Email)));
}
} }
} }

View file

@ -564,6 +564,8 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterModel model) public async Task<IActionResult> Register(RegisterModel model)
{ {
model.Email = model.Email?.Trim();
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email }; var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };