Fix account and backup admin settings flows
This commit is contained in:
@@ -139,7 +139,13 @@ public sealed class AuthAndSystemControllerTests
|
||||
var summarizer = new Mock<ISummarizerService>();
|
||||
summarizer.Setup(x => x.RunProbeAsync(It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
|
||||
|
||||
var controller = new AdminSystemController(BuildConfig(), new AppPaths(BuildConfig(), new FakeHostEnv()), null!, summarizer.Object, new FakeEnv());
|
||||
var controller = new AdminSystemController(
|
||||
BuildConfig(),
|
||||
new AppPaths(BuildConfig(), new FakeHostEnv()),
|
||||
null!,
|
||||
summarizer.Object,
|
||||
new FakeEnv(),
|
||||
Mock.Of<IEmailSettingsResolver>());
|
||||
|
||||
var result = await controller.RunSummarizerProbe(CancellationToken.None);
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using JobTrackerApi.Controllers;
|
||||
using JobTrackerApi.Data;
|
||||
using JobTrackerApi.Models;
|
||||
using JobTrackerApi.Services;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace JobTrackerApi.Tests;
|
||||
|
||||
public sealed class BackupControllerTests
|
||||
{
|
||||
[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" });
|
||||
db.JobApplications.Add(new JobApplication { JobTitle = "Backend Developer", OwnerUserId = "user-1" });
|
||||
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<BackupController>(), provider);
|
||||
|
||||
var result = await controller.Encrypted(CancellationToken.None);
|
||||
|
||||
var file = Assert.IsType<FileContentResult>(result);
|
||||
Assert.Equal("application/octet-stream", file.ContentType);
|
||||
Assert.EndsWith(".jtbackup", file.FileDownloadName);
|
||||
Assert.NotEmpty(file.FileContents);
|
||||
}
|
||||
|
||||
private static JobTrackerContext CreateDb()
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<JobTrackerContext>()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.Options;
|
||||
var currentUser = new Mock<ICurrentUserService>();
|
||||
currentUser.SetupGet(x => x.UserId).Returns("user-1");
|
||||
return new JobTrackerContext(options, currentUser.Object);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using JobTrackerApi.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.IdentityModel.Protocols;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace JobTrackerApi.Tests;
|
||||
|
||||
public sealed class GoogleTokenValidatorTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ValidateAsync_accepts_subject_mapped_to_nameidentifier_claim()
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["Auth:GoogleClientId"] = "client-123",
|
||||
})
|
||||
.Build();
|
||||
|
||||
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("super-secret-signing-key-super-secret"));
|
||||
var oidc = new OpenIdConnectConfiguration();
|
||||
oidc.SigningKeys.Add(signingKey);
|
||||
|
||||
var configManager = new Mock<IConfigurationManager<OpenIdConnectConfiguration>>();
|
||||
configManager.Setup(x => x.GetConfigurationAsync(It.IsAny<CancellationToken>())).ReturnsAsync(oidc);
|
||||
|
||||
var token = new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(
|
||||
issuer: "https://accounts.google.com",
|
||||
audience: "client-123",
|
||||
claims: new[]
|
||||
{
|
||||
new Claim(JwtRegisteredClaimNames.Sub, "google-subject-1"),
|
||||
new Claim("email", "demo@example.com"),
|
||||
new Claim("email_verified", "true"),
|
||||
new Claim("given_name", "Demo"),
|
||||
new Claim("family_name", "User"),
|
||||
new Claim("name", "Demo User"),
|
||||
},
|
||||
expires: DateTime.UtcNow.AddMinutes(10),
|
||||
signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)));
|
||||
|
||||
var validator = new GoogleTokenValidator(config, configManager.Object);
|
||||
var result = await validator.ValidateAsync(token);
|
||||
|
||||
Assert.Equal("google-subject-1", result.Subject);
|
||||
Assert.Equal("demo@example.com", result.Email);
|
||||
Assert.True(result.EmailVerified);
|
||||
Assert.Equal("Demo", result.GivenName);
|
||||
Assert.Equal("User", result.FamilyName);
|
||||
Assert.Equal("Demo User", result.Name);
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,96 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
Assert.Contains(payload.KeyPoints, item => item.Contains("recruiter language", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Generate_application_package_passes_typed_structured_cv_context_to_summarizer()
|
||||
{
|
||||
await using var db = CreateDb();
|
||||
var company = new Company
|
||||
{
|
||||
Name = "Acme",
|
||||
OwnerUserId = "user-1"
|
||||
};
|
||||
db.Companies.Add(company);
|
||||
db.Users.Add(new ApplicationUser
|
||||
{
|
||||
Id = "user-1",
|
||||
UserName = "user@example.test",
|
||||
Email = "user@example.test",
|
||||
ProfileCvText = "Built APIs and shipped backend work.",
|
||||
ProfileCvStructureJson = """
|
||||
{
|
||||
"version": "1",
|
||||
"contact": {
|
||||
"fullName": "Demo User",
|
||||
"headline": "Backend Developer",
|
||||
"email": "user@example.test",
|
||||
"location": "Oslo"
|
||||
},
|
||||
"summary": ["Backend-focused developer with strong API delivery experience."],
|
||||
"jobs": [
|
||||
{
|
||||
"title": "System Developer",
|
||||
"company": "Acme Consulting",
|
||||
"location": "Oslo",
|
||||
"start": "2020",
|
||||
"end": "2024",
|
||||
"isCurrent": false,
|
||||
"bullets": ["Owned .NET API delivery across multiple services."],
|
||||
"skills": [".NET", "SQL", "APIs"]
|
||||
}
|
||||
],
|
||||
"education": [],
|
||||
"skills": [".NET", "SQL", "APIs"],
|
||||
"languages": [{ "name": "English", "level": "Native" }],
|
||||
"interests": [],
|
||||
"otherSections": []
|
||||
}
|
||||
"""
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var job = new JobApplication
|
||||
{
|
||||
JobTitle = "Backend Developer",
|
||||
CompanyId = company.Id,
|
||||
OwnerUserId = "user-1",
|
||||
Description = "Need .NET API ownership and strong SQL skills."
|
||||
};
|
||||
db.JobApplications.Add(job);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
string? capturedContext = null;
|
||||
var summarizer = new Mock<ISummarizerService>();
|
||||
summarizer
|
||||
.Setup(service => service.SummarizeSectionAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.ReturnsAsync((string instruction, string context, int _, int __) =>
|
||||
{
|
||||
if (instruction.Contains("Rewrite the candidate CV", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
capturedContext = context;
|
||||
return "Tailored CV";
|
||||
}
|
||||
|
||||
if (instruction.Contains("List up to 4 concrete application-package signals", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "Lead with .NET API ownership.";
|
||||
}
|
||||
|
||||
return "Draft";
|
||||
});
|
||||
|
||||
var controller = CreateController(db, summarizer.Object, "user-1");
|
||||
var result = await controller.GenerateApplicationPackage(job.Id, null, null, null, CancellationToken.None);
|
||||
|
||||
Assert.IsType<OkObjectResult>(result.Result);
|
||||
Assert.NotNull(capturedContext);
|
||||
Assert.Contains("Structured CV:", capturedContext);
|
||||
Assert.Contains("Name: Demo User", capturedContext);
|
||||
Assert.Contains("Skills:\n.NET, SQL, APIs", capturedContext);
|
||||
Assert.Contains("Work Experience:", capturedContext);
|
||||
Assert.Contains("Owned .NET API delivery across multiple services.", capturedContext);
|
||||
}
|
||||
|
||||
private static JobApplicationsController CreateController(JobTrackerContext db, ISummarizerService summarizer, string userId)
|
||||
{
|
||||
var controller = new JobApplicationsController(db, summarizer, Mock.Of<IAppEmailSender>(), CreateUserManager().Object, NullLogger<JobApplicationsController>.Instance);
|
||||
|
||||
Reference in New Issue
Block a user