Blog: add test guarding the display-template fix + document test architecture
Le commit 2 a fixé la NPE du /BlogSpot/Details/{id} en passant
le display template par UserDisplayHelpers.AvatarSrc, qui
défend contre un UserName null. Ce commit complète le filet
de non-régression et pose la doc d'architecture des tests.
- ApplicationUserDisplayTemplateTests : assert que le cshtml ne
concatène plus directement Model.UserName (ancien code fautif)
et qu'il utilise bien le helper. Si quelqu'un revert la ligne
4 du cshtml, les tests cassent. Les autres usages de
Model.UserName (alt, title, asp-route-id) sont autorisés : ils
ne sont pas la cause du 500, juste laids si null.
- doc/testing.md : vue d'ensemble de la stratégie de test
(conventions NonRegression/Mandatory/Smoke/Controllers, EF
in-memory via InMemoryDatabaseRoot partagé, auth stubs,
quand ne pas écrire de test).
- src/Yavsc.Tests.Shared/README.md : détails du scaffold partagé
(WebHostFixture + son cycle de vie et ses hooks,
TestAuthPolicyProvider, TestTokenIssuer) et des deux
spécialisations dans le repo
(Yavsc.Org.Tests.WebServerFixture et
Yavsc.Blogs.Tests.BlogsWebServerFixture).
- doc/README.md : entrée vers testing.md dans l'index.
This commit is contained in:
parent
bbdcc7f2ad
commit
cb7526de9d
4 changed files with 307 additions and 0 deletions
|
|
@ -0,0 +1,69 @@
|
|||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Yavsc.Org.Tests.NonRegression;
|
||||
|
||||
/// <summary>
|
||||
/// Régression du 500 sur <c>GET /BlogSpot/Details/{id}</c> (auteur
|
||||
/// sans <c>UserName</c>) : le display template
|
||||
/// <c>ApplicationUser.cshtml</c> ne doit plus accéder à
|
||||
/// <c>Model.UserName</c> directement. Toute lecture passe par
|
||||
/// <c>UserDisplayHelpers.AvatarSrc</c>, qui défend contre
|
||||
/// <c>null</c> et contre les chaînes vides/whitespace.
|
||||
///
|
||||
/// On ne compile pas la vue Razor ici (coût de mise en place
|
||||
/// disproportionné pour un seul display template) ; on asserte
|
||||
/// statiquement que le cshtml ne porte plus l'accès fautif. Si
|
||||
/// quelqu'un revert la ligne, ce test casse.
|
||||
/// </summary>
|
||||
public class ApplicationUserDisplayTemplateTests
|
||||
{
|
||||
[Fact]
|
||||
public void ApplicationUser_cshtml_does_not_construct_avatar_path_from_Model_UserName()
|
||||
{
|
||||
// L'invariant qu'on protège : l'URL d'avatar ne doit plus
|
||||
// être construite à partir de Model.UserName direct (le
|
||||
// commit 2 du fix). Cette construction était la cause du
|
||||
// 500 sur GET /BlogSpot/Details/{id} : avec
|
||||
// <Nullable>enable</Nullable>, Razor émet un null-check
|
||||
// implicite sur l'expression, et lève NPE si UserName est
|
||||
// null. Le helper AvatarSrc défend contre ce cas.
|
||||
//
|
||||
// On n'interdit pas les autres usages de Model.UserName
|
||||
// (alt, title, asp-route-id) : Razor les rend en chaîne
|
||||
// vide si null, sans NPE. C'est laid, pas cassé.
|
||||
var path = ResolveTemplatePath();
|
||||
var content = File.ReadAllText(path);
|
||||
|
||||
// L'ancien code fautif concaténait directement
|
||||
// "/Avatars/" + Model.UserName + ".s.png".
|
||||
Assert.DoesNotContain("Model.UserName + ", content);
|
||||
Assert.DoesNotContain("Model.UserName+", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplicationUser_cshtml_uses_the_null_safe_helper_for_avatar()
|
||||
{
|
||||
var path = ResolveTemplatePath();
|
||||
var content = File.ReadAllText(path);
|
||||
|
||||
Assert.Contains("UserDisplayHelpers.AvatarSrc", content);
|
||||
}
|
||||
|
||||
private static string ResolveTemplatePath()
|
||||
{
|
||||
// Le test s'exécute depuis src/Yavsc.Org.Tests/bin/...,
|
||||
// on remonte pour trouver la vue source.
|
||||
var dir = AppContext.BaseDirectory;
|
||||
for (var i = 0; i < 8 && dir is not null; i++)
|
||||
{
|
||||
var candidate = Path.Combine(dir,
|
||||
"src", "Yavsc.Org", "Views", "Shared",
|
||||
"DisplayTemplates", "ApplicationUser.cshtml");
|
||||
if (File.Exists(candidate)) return candidate;
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
}
|
||||
throw new FileNotFoundException(
|
||||
"Could not locate ApplicationUser.cshtml from " + AppContext.BaseDirectory);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue