Blogs: fix delete returning 40x despite the file being removed
DeleteUserDirOrFile (and DeleteUserFile) read FileInfo.Length AFTER fi.Delete(), and FileInfo.Length throws FileNotFoundException once the file is gone. The controller's catch turned that into a 400, so the user saw "le fichier n'existe pas sur le serveur" while the delete had in fact succeeded. Capture the length before deleting. Adds FileSystemApiTests.Delete_fs_removes_the_file_and_returns_200 (asserts 200 + file gone from disk). 8/8 FileSystemApiTests pass. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
f1a17cd8fe
commit
7844449c99
3 changed files with 53 additions and 2 deletions
|
|
@ -82,6 +82,15 @@ et négociation HTTP/3 côté client PostIt.
|
|||
désactivé (grisé) et inerte au clic. Corrigé en
|
||||
`$parent[ContentPage].((vm:XxxViewModel)DataContext).Cmd` (syntaxe
|
||||
déjà en vigueur dans `CirclesPage` / `EstimateListPage`).
|
||||
* [Yavsc.Blogs] La suppression d'un fichier (`DELETE api/v1/fs/{name}`)
|
||||
renvoyait un 40x alors que le fichier était bien supprimé du disque.
|
||||
`DeleteUserDirOrFile` (et `DeleteUserFile`) lisaient
|
||||
`FileInfo.Length` **après** `fi.Delete()` ; or `FileInfo.Length`
|
||||
lève `FileNotFoundException` une fois le fichier disparu — le `catch`
|
||||
du contrôleur transformait cette exception en 400, d'où le message
|
||||
perçu « le fichier n'existe pas sur le serveur » tandis que la
|
||||
suppression avait réussi. La taille est désormais capturée avant la
|
||||
suppression.
|
||||
|
||||
## [1.0.8-rc17] - unstable
|
||||
|
||||
|
|
|
|||
|
|
@ -363,4 +363,35 @@ public sealed class FileSystemApiTests : IClassFixture<BlogsWebServerFixture>
|
|||
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regression for the "delete returns 40x yet the file is gone"
|
||||
/// report: <c>DeleteUserDirOrFile</c> read <c>FileInfo.Length</c>
|
||||
/// <b>after</b> <c>fi.Delete()</c>, and <c>FileInfo.Length</c>
|
||||
/// throws <c>FileNotFoundException</c> once the file no longer
|
||||
/// exists. The controller's <c>catch</c> turned that into a 400
|
||||
/// even though the file had already been removed — the user saw
|
||||
/// "le fichier n'existe pas sur le serveur" while the delete in
|
||||
/// fact succeeded. This test asserts a clean 200 and that the
|
||||
/// file is gone from disk.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Delete_fs_removes_the_file_and_returns_200()
|
||||
{
|
||||
_fixture.ResetDatabase();
|
||||
_fixture.SeedUser("alice");
|
||||
|
||||
var bytes = System.Text.Encoding.UTF8.GetBytes("delete me");
|
||||
WritePhysicalFile(_fixture, "alice", "doomed.txt", bytes);
|
||||
|
||||
using var http = NewClient("alice");
|
||||
var response = await http.DeleteAsync(
|
||||
"/api/v1/fs/doomed.txt", TestContext.Current.CancellationToken);
|
||||
var body = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.True(response.StatusCode == HttpStatusCode.OK,
|
||||
$"Expected 200, got {(int)response.StatusCode} ({response.StatusCode}): {body}");
|
||||
Assert.False(File.Exists(PhysicalFile(_fixture, "alice", "doomed.txt")),
|
||||
"The file must be gone from disk after a successful delete.");
|
||||
}
|
||||
}
|
||||
|
|
@ -70,8 +70,12 @@ namespace Yavsc.Server.Helpers
|
|||
var root = Path.Combine(siteSettings.Blog, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileName));
|
||||
if (!fi.Exists) return;
|
||||
// Capture the length BEFORE deleting: FileInfo.Length throws
|
||||
// FileNotFoundException once the file is gone, which would
|
||||
// surface as a 400 even though the delete already succeeded.
|
||||
var length = fi.Length;
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
user.DiskUsage -= length;
|
||||
}
|
||||
|
||||
public static FsOperationInfo DeleteUserDirOrFile(this ApplicationUser user, string dirName, SiteSettings siteSettings)
|
||||
|
|
@ -85,8 +89,15 @@ namespace Yavsc.Server.Helpers
|
|||
{
|
||||
var fi = new FileInfo(Path.Combine(root, dirName));
|
||||
if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent" };
|
||||
// Capture the length BEFORE deleting: FileInfo.Length
|
||||
// throws FileNotFoundException once the file is gone, so
|
||||
// reading it after fi.Delete() would throw — the caller's
|
||||
// catch turns that into a 400 even though the file was
|
||||
// already removed (the user sees "file does not exist"
|
||||
// while the delete in fact succeeded).
|
||||
var length = fi.Length;
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
user.DiskUsage -= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue