using System.Reflection; using JobTrackerApi.Controllers; using JobTrackerApi.Data; using JobTrackerApi.Models; using JobTrackerApi.Services; using JobTrackerApi.Tests.TestSupport; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging.Abstractions; using Xunit; namespace JobTrackerApi.Tests; public sealed class BackupControllerTests { [Fact] public void Backup_controller_requires_local_authorization() { var attribute = typeof(BackupController).GetCustomAttribute(); Assert.NotNull(attribute); Assert.Equal("local", attribute!.AuthenticationSchemes); } [Fact] public void Export_controller_requires_local_authorization() { var attribute = typeof(ExportController).GetCustomAttribute(); Assert.NotNull(attribute); Assert.Equal("local", attribute!.AuthenticationSchemes); } [Fact] public async Task Encrypted_returns_file_payload_on_non_windows_platforms_too() { await using var db = CreateDb(); db.Companies.Add(new Company { Name = "Acme", OwnerUserId = "user-1" }); var job = new JobApplication { JobTitle = "Backend Developer", OwnerUserId = "user-1" }; db.JobApplications.Add(job); await db.SaveChangesAsync(); db.EmailSendAttempts.Add(new EmailSendAttempt { Id = Guid.NewGuid(), OwnerUserId = "user-1", JobApplicationId = job.Id, Provider = "gmail", ClientRequestId = Guid.NewGuid().ToString(), PayloadHash = new string('a', 64), Status = EmailSendStatuses.Sent, ProviderMessageId = "synthetic-message-id", CreatedAtUtc = DateTime.UtcNow, CompletedAtUtc = DateTime.UtcNow, }); await db.SaveChangesAsync(); var provider = DataProtectionProvider.Create(new DirectoryInfo(Path.Combine(Path.GetTempPath(), $"jobtracker-tests-{Guid.NewGuid():N}"))); var controller = new BackupController(db, new NullLogger(), provider); var result = await controller.Encrypted(CancellationToken.None); var file = Assert.IsType(result); Assert.Equal("application/octet-stream", file.ContentType); Assert.EndsWith(".jtbackup", file.FileDownloadName); Assert.NotEmpty(file.FileContents); var protectedText = System.Text.Encoding.UTF8.GetString(file.FileContents); var json = Convert.FromBase64String(provider.CreateProtector("JobTrackerApi.Backup.v1").Unprotect(protectedText)); using var document = System.Text.Json.JsonDocument.Parse(json); var attempt = Assert.Single(document.RootElement.GetProperty("Data").GetProperty("EmailSendAttempts").EnumerateArray()); Assert.Equal("gmail", attempt.GetProperty("Provider").GetString()); Assert.Equal("sent", attempt.GetProperty("Status").GetString()); Assert.False(attempt.TryGetProperty("PayloadHash", out _)); } private static JobTrackerContext CreateDb() { return TestHostFactory.CreateInMemoryDb(); } }