Bust stale critical source image caches
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -49,10 +49,18 @@ api.MapGet("/tables/critical/{slug}/cells/{resultId:int}", async (string slug, i
|
||||
var result = await lookupService.GetCriticalCellEditorAsync(slug, resultId, cancellationToken);
|
||||
return result is null ? Results.NotFound() : Results.Ok(result);
|
||||
});
|
||||
api.MapGet("/tables/critical/{slug}/cells/{resultId:int}/source-image", async (string slug, int resultId, LookupService lookupService, CancellationToken cancellationToken) =>
|
||||
api.MapGet("/tables/critical/{slug}/cells/{resultId:int}/source-image", async (string slug, int resultId, LookupService lookupService, HttpContext httpContext, CancellationToken cancellationToken) =>
|
||||
{
|
||||
var filePath = await lookupService.GetCriticalSourceImagePathAsync(slug, resultId, cancellationToken);
|
||||
return filePath is null ? Results.NotFound() : Results.File(filePath, "image/png");
|
||||
if (filePath is null)
|
||||
{
|
||||
return Results.NotFound();
|
||||
}
|
||||
|
||||
httpContext.Response.Headers.CacheControl = "no-store, no-cache, max-age=0";
|
||||
httpContext.Response.Headers.Pragma = "no-cache";
|
||||
httpContext.Response.Headers.Expires = "0";
|
||||
return Results.File(filePath, "image/png");
|
||||
});
|
||||
api.MapPost("/tables/critical/{slug}/cells/{resultId:int}/reparse", async (string slug, int resultId, CriticalCellReparseRequest request, LookupService lookupService, CancellationToken cancellationToken) =>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using RolemasterDb.App.Data;
|
||||
using RolemasterDb.App.Domain;
|
||||
using RolemasterDb.App.Features;
|
||||
@@ -25,22 +24,9 @@ public sealed class LookupServiceCurationIntegrationTests
|
||||
Assert.NotNull(initialResponse);
|
||||
Assert.False(initialResponse!.IsCurated);
|
||||
Assert.Equal(2, initialResponse.SourcePageNumber);
|
||||
Assert.Equal($"/api/tables/critical/slash/cells/{resultId}/source-image", initialResponse.SourceImageUrl);
|
||||
Assert.StartsWith($"/api/tables/critical/slash/cells/{resultId}/source-image?v=", initialResponse.SourceImageUrl, StringComparison.Ordinal);
|
||||
|
||||
var updateRequest = new CriticalCellUpdateRequest(
|
||||
initialResponse.RawCellText,
|
||||
initialResponse.QuickParseInput,
|
||||
initialResponse.DescriptionText,
|
||||
initialResponse.RawAffixText,
|
||||
initialResponse.ParseStatus,
|
||||
initialResponse.ParsedJson,
|
||||
true,
|
||||
initialResponse.IsDescriptionOverridden,
|
||||
initialResponse.IsRawAffixTextOverridden,
|
||||
initialResponse.AreEffectsOverridden,
|
||||
initialResponse.AreBranchesOverridden,
|
||||
initialResponse.Effects,
|
||||
initialResponse.Branches);
|
||||
var updateRequest = new CriticalCellUpdateRequest(initialResponse.RawCellText, initialResponse.QuickParseInput, initialResponse.DescriptionText, initialResponse.RawAffixText, initialResponse.ParseStatus, initialResponse.ParsedJson, true, initialResponse.IsDescriptionOverridden, initialResponse.IsRawAffixTextOverridden, initialResponse.AreEffectsOverridden, initialResponse.AreBranchesOverridden, initialResponse.Effects, initialResponse.Branches);
|
||||
|
||||
var updatedResponse = await lookupService.UpdateCriticalCellAsync("slash", resultId, updateRequest);
|
||||
Assert.NotNull(updatedResponse);
|
||||
@@ -56,6 +42,32 @@ public sealed class LookupServiceCurationIntegrationTests
|
||||
Assert.Equal(initialResponse.SourceImageUrl, reopenedResponse.SourceImageUrl);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Lookup_service_changes_source_image_url_when_source_provenance_changes()
|
||||
{
|
||||
var databasePath = CreateEmptyDatabasePath();
|
||||
var repositoryRoot = CreateTemporaryRepositoryRoot();
|
||||
var locator = new CriticalImportArtifactLocator(new TestHostEnvironment(Path.Combine(repositoryRoot, "src", "RolemasterDb.App")));
|
||||
|
||||
await SeedCriticalResultAsync(databasePath, "slash/cells/source-cell.png", 2);
|
||||
WriteSourceImage(repositoryRoot, "slash/cells/source-cell.png");
|
||||
WriteSourceImage(repositoryRoot, "slash/cells/source-cell-v2.png");
|
||||
|
||||
var lookupService = new LookupService(CreateDbContextFactory(databasePath), locator);
|
||||
var resultId = await GetResultIdAsync(databasePath);
|
||||
|
||||
var initialResponse = await lookupService.GetCriticalCellEditorAsync("slash", resultId);
|
||||
Assert.NotNull(initialResponse);
|
||||
Assert.StartsWith($"/api/tables/critical/slash/cells/{resultId}/source-image?v=", initialResponse!.SourceImageUrl, StringComparison.Ordinal);
|
||||
|
||||
await UpdateSourceMetadataAsync(databasePath, resultId, sourcePageNumber: 4, sourceImagePath: "slash/cells/source-cell-v2.png", sourceImageCropJson: "{\"pageNumber\":4,\"boundsLeft\":12}");
|
||||
|
||||
var reopenedResponse = await lookupService.GetCriticalCellEditorAsync("slash", resultId);
|
||||
Assert.NotNull(reopenedResponse);
|
||||
Assert.StartsWith($"/api/tables/critical/slash/cells/{resultId}/source-image?v=", reopenedResponse!.SourceImageUrl, StringComparison.Ordinal);
|
||||
Assert.NotEqual(initialResponse.SourceImageUrl, reopenedResponse.SourceImageUrl);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Lookup_service_clears_curated_state_when_any_content_is_edited()
|
||||
{
|
||||
@@ -72,29 +84,13 @@ public sealed class LookupServiceCurationIntegrationTests
|
||||
var initialResponse = await lookupService.GetCriticalCellEditorAsync("slash", resultId);
|
||||
Assert.NotNull(initialResponse);
|
||||
|
||||
var markCuratedRequest = new CriticalCellUpdateRequest(
|
||||
initialResponse!.RawCellText,
|
||||
initialResponse.QuickParseInput,
|
||||
initialResponse.DescriptionText,
|
||||
initialResponse.RawAffixText,
|
||||
initialResponse.ParseStatus,
|
||||
initialResponse.ParsedJson,
|
||||
true,
|
||||
initialResponse.IsDescriptionOverridden,
|
||||
initialResponse.IsRawAffixTextOverridden,
|
||||
initialResponse.AreEffectsOverridden,
|
||||
initialResponse.AreBranchesOverridden,
|
||||
initialResponse.Effects,
|
||||
initialResponse.Branches);
|
||||
var markCuratedRequest = new CriticalCellUpdateRequest(initialResponse!.RawCellText, initialResponse.QuickParseInput, initialResponse.DescriptionText, initialResponse.RawAffixText, initialResponse.ParseStatus, initialResponse.ParsedJson, true, initialResponse.IsDescriptionOverridden, initialResponse.IsRawAffixTextOverridden, initialResponse.AreEffectsOverridden, initialResponse.AreBranchesOverridden, initialResponse.Effects, initialResponse.Branches);
|
||||
|
||||
var curatedResponse = await lookupService.UpdateCriticalCellAsync("slash", resultId, markCuratedRequest);
|
||||
Assert.NotNull(curatedResponse);
|
||||
Assert.True(curatedResponse!.IsCurated);
|
||||
|
||||
var editedRequest = markCuratedRequest with
|
||||
{
|
||||
DescriptionText = "Edited description after curation."
|
||||
};
|
||||
var editedRequest = markCuratedRequest with { DescriptionText = "Edited description after curation." };
|
||||
|
||||
var editedResponse = await lookupService.UpdateCriticalCellAsync("slash", resultId, editedRequest);
|
||||
Assert.NotNull(editedResponse);
|
||||
@@ -123,44 +119,12 @@ public sealed class LookupServiceCurationIntegrationTests
|
||||
Assert.NotNull(initialResponse);
|
||||
Assert.False(initialResponse!.IsCurated);
|
||||
|
||||
var reparsedResponse = await lookupService.ReparseCriticalCellAsync(
|
||||
"slash",
|
||||
resultId,
|
||||
new CriticalCellUpdateRequest(
|
||||
initialResponse.RawCellText,
|
||||
"Edited quick parse input.",
|
||||
initialResponse.DescriptionText,
|
||||
initialResponse.RawAffixText,
|
||||
initialResponse.ParseStatus,
|
||||
initialResponse.ParsedJson,
|
||||
initialResponse.IsCurated,
|
||||
initialResponse.IsDescriptionOverridden,
|
||||
initialResponse.IsRawAffixTextOverridden,
|
||||
initialResponse.AreEffectsOverridden,
|
||||
initialResponse.AreBranchesOverridden,
|
||||
initialResponse.Effects,
|
||||
initialResponse.Branches));
|
||||
var reparsedResponse = await lookupService.ReparseCriticalCellAsync("slash", resultId, new CriticalCellUpdateRequest(initialResponse.RawCellText, "Edited quick parse input.", initialResponse.DescriptionText, initialResponse.RawAffixText, initialResponse.ParseStatus, initialResponse.ParsedJson, initialResponse.IsCurated, initialResponse.IsDescriptionOverridden, initialResponse.IsRawAffixTextOverridden, initialResponse.AreEffectsOverridden, initialResponse.AreBranchesOverridden, initialResponse.Effects, initialResponse.Branches));
|
||||
|
||||
Assert.NotNull(reparsedResponse);
|
||||
Assert.False(reparsedResponse!.IsCurated);
|
||||
|
||||
var curatedResponse = await lookupService.UpdateCriticalCellAsync(
|
||||
"slash",
|
||||
resultId,
|
||||
new CriticalCellUpdateRequest(
|
||||
reparsedResponse.RawCellText,
|
||||
reparsedResponse.QuickParseInput,
|
||||
reparsedResponse.DescriptionText,
|
||||
reparsedResponse.RawAffixText,
|
||||
reparsedResponse.ParseStatus,
|
||||
reparsedResponse.ParsedJson,
|
||||
true,
|
||||
reparsedResponse.IsDescriptionOverridden,
|
||||
reparsedResponse.IsRawAffixTextOverridden,
|
||||
reparsedResponse.AreEffectsOverridden,
|
||||
reparsedResponse.AreBranchesOverridden,
|
||||
reparsedResponse.Effects,
|
||||
reparsedResponse.Branches));
|
||||
var curatedResponse = await lookupService.UpdateCriticalCellAsync("slash", resultId, new CriticalCellUpdateRequest(reparsedResponse.RawCellText, reparsedResponse.QuickParseInput, reparsedResponse.DescriptionText, reparsedResponse.RawAffixText, reparsedResponse.ParseStatus, reparsedResponse.ParsedJson, true, reparsedResponse.IsDescriptionOverridden, reparsedResponse.IsRawAffixTextOverridden, reparsedResponse.AreEffectsOverridden, reparsedResponse.AreBranchesOverridden, reparsedResponse.Effects, reparsedResponse.Branches));
|
||||
|
||||
Assert.NotNull(curatedResponse);
|
||||
Assert.True(curatedResponse!.IsCurated);
|
||||
@@ -263,26 +227,29 @@ public sealed class LookupServiceCurationIntegrationTests
|
||||
private static async Task<int> GetResultIdAsync(string databasePath)
|
||||
{
|
||||
await using var dbContext = CreateDbContext(databasePath);
|
||||
return await dbContext.CriticalResults
|
||||
.Where(item => item.CriticalTable.Slug == "slash")
|
||||
.Select(item => item.Id)
|
||||
.SingleAsync();
|
||||
return await dbContext.CriticalResults.Where(item => item.CriticalTable.Slug == "slash").Select(item => item.Id).SingleAsync();
|
||||
}
|
||||
|
||||
private static async Task UpdateSourceMetadataAsync(string databasePath, int resultId, int sourcePageNumber, string sourceImagePath, string sourceImageCropJson)
|
||||
{
|
||||
await using var dbContext = CreateDbContext(databasePath);
|
||||
var result = await dbContext.CriticalResults.SingleAsync(item => item.Id == resultId);
|
||||
result.SourcePageNumber = sourcePageNumber;
|
||||
result.SourceImagePath = sourceImagePath;
|
||||
result.SourceImageCropJson = sourceImageCropJson;
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static RolemasterDbContext CreateDbContext(string databasePath)
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<RolemasterDbContext>()
|
||||
.UseSqlite($"Data Source={databasePath}")
|
||||
.Options;
|
||||
var options = new DbContextOptionsBuilder<RolemasterDbContext>().UseSqlite($"Data Source={databasePath}").Options;
|
||||
|
||||
return new RolemasterDbContext(options);
|
||||
}
|
||||
|
||||
private static IDbContextFactory<RolemasterDbContext> CreateDbContextFactory(string databasePath)
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<RolemasterDbContext>()
|
||||
.UseSqlite($"Data Source={databasePath}")
|
||||
.Options;
|
||||
var options = new DbContextOptionsBuilder<RolemasterDbContext>().UseSqlite($"Data Source={databasePath}").Options;
|
||||
|
||||
return new TestRolemasterDbContextFactory(options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user