From 47c72de2831df6fb204c3af267a04638774d5019 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Sun, 22 Mar 2026 14:00:49 +0100 Subject: [PATCH] test: add backend security regression test foundation --- Job tracker.sln | 27 +++++++++++++++++++ .../AttachmentsControllerTests.cs | 23 ++++++++++++++++ .../JobTrackerApi.Tests.csproj | 21 +++++++++++++++ JobTrackerApi.Tests/OwnershipGuardTests.cs | 22 +++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 JobTrackerApi.Tests/AttachmentsControllerTests.cs create mode 100644 JobTrackerApi.Tests/JobTrackerApi.Tests.csproj create mode 100644 JobTrackerApi.Tests/OwnershipGuardTests.cs diff --git a/Job tracker.sln b/Job tracker.sln index e8ee8ae..8438c36 100644 --- a/Job tracker.sln +++ b/Job tracker.sln @@ -1,19 +1,46 @@ + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.2.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JobTrackerApi", "JobTrackerApi\JobTrackerApi.csproj", "{C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JobTrackerApi.Tests", "JobTrackerApi.Tests\JobTrackerApi.Tests.csproj", "{4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|x64.ActiveCfg = Debug|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|x64.Build.0 = Debug|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|x86.ActiveCfg = Debug|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Debug|x86.Build.0 = Debug|Any CPU {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|Any CPU.ActiveCfg = Release|Any CPU {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|Any CPU.Build.0 = Release|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|x64.ActiveCfg = Release|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|x64.Build.0 = Release|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|x86.ActiveCfg = Release|Any CPU + {C5DB7EBB-7221-0C11-4A27-A9C4AB5BE51D}.Release|x86.Build.0 = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|x64.ActiveCfg = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|x64.Build.0 = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|x86.ActiveCfg = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Debug|x86.Build.0 = Debug|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|Any CPU.Build.0 = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|x64.ActiveCfg = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|x64.Build.0 = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|x86.ActiveCfg = Release|Any CPU + {4AA1218D-B33E-4E8B-8C46-EB85A5FE615C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/JobTrackerApi.Tests/AttachmentsControllerTests.cs b/JobTrackerApi.Tests/AttachmentsControllerTests.cs new file mode 100644 index 0000000..ed6680c --- /dev/null +++ b/JobTrackerApi.Tests/AttachmentsControllerTests.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using JobTrackerApi.Controllers; +using Xunit; + +namespace JobTrackerApi.Tests; + +public sealed class AttachmentsControllerTests +{ + [Fact] + public void Allowed_extensions_include_common_document_and_image_formats() + { + var field = typeof(AttachmentsController).GetField("AllowedExtensions", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(field); + + var allowed = Assert.IsAssignableFrom(field!.GetValue(null)); + var values = allowed.Cast().ToHashSet(StringComparer.OrdinalIgnoreCase); + + Assert.Contains(".pdf", values); + Assert.Contains(".docx", values); + Assert.Contains(".png", values); + Assert.DoesNotContain(".exe", values); + } +} diff --git a/JobTrackerApi.Tests/JobTrackerApi.Tests.csproj b/JobTrackerApi.Tests/JobTrackerApi.Tests.csproj new file mode 100644 index 0000000..ea1de27 --- /dev/null +++ b/JobTrackerApi.Tests/JobTrackerApi.Tests.csproj @@ -0,0 +1,21 @@ + + + net9.0 + enable + enable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + diff --git a/JobTrackerApi.Tests/OwnershipGuardTests.cs b/JobTrackerApi.Tests/OwnershipGuardTests.cs new file mode 100644 index 0000000..5f2262d --- /dev/null +++ b/JobTrackerApi.Tests/OwnershipGuardTests.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using JobTrackerApi.Controllers; +using Xunit; + +namespace JobTrackerApi.Tests; + +public sealed class OwnershipGuardTests +{ + [Fact] + public void Attachments_controller_has_owned_attachment_lookup_helper() + { + var method = typeof(AttachmentsController).GetMethod("FindOwnedAttachmentAsync", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull(method); + } + + [Fact] + public void Correspondence_controller_has_owned_message_lookup_helper() + { + var method = typeof(CorrespondenceController).GetMethod("FindOwnedMessageAsync", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull(method); + } +}