[FA-misc] Refresh button, UI mostly gold
This commit is contained in:
@@ -162,4 +162,138 @@ public class NovelUpdateServiceTests
|
||||
}
|
||||
|
||||
private record NovelCreateResult(Novel Novel, Chapter Chapter);
|
||||
|
||||
#region UpdateImage Tests
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateImage_sets_NewPath_on_image_without_chapter()
|
||||
{
|
||||
// Arrange
|
||||
using var dbContext = CreateDbContext();
|
||||
var image = new Image
|
||||
{
|
||||
OriginalPath = "http://original/cover.jpg",
|
||||
NewPath = null
|
||||
};
|
||||
dbContext.Images.Add(image);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var adapter = Substitute.For<ISourceAdapter>();
|
||||
var eventBus = Substitute.For<IEventBus>();
|
||||
var service = CreateService(dbContext, adapter, eventBus);
|
||||
|
||||
var newUrl = "https://cdn.example.com/uploaded/cover.jpg";
|
||||
|
||||
// Act
|
||||
await service.UpdateImage(image.Id, newUrl);
|
||||
|
||||
// Assert
|
||||
var updatedImage = await dbContext.Images.FindAsync(image.Id);
|
||||
updatedImage!.NewPath.Should().Be(newUrl);
|
||||
updatedImage.OriginalPath.Should().Be("http://original/cover.jpg");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateImage_updates_chapter_body_html_with_new_url()
|
||||
{
|
||||
// Arrange
|
||||
using var dbContext = CreateDbContext();
|
||||
var source = new Source { Name = "Demo", Key = "demo", Url = "http://demo" };
|
||||
var (novel, chapter) = CreateNovelWithSingleChapter(dbContext, source);
|
||||
|
||||
var image = new Image
|
||||
{
|
||||
OriginalPath = "http://original/image.jpg",
|
||||
NewPath = null,
|
||||
Chapter = chapter
|
||||
};
|
||||
chapter.Images.Add(image);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
// Set up the chapter body with an img tag referencing the image by ID (as PullChapterContents does)
|
||||
var pendingUrl = "https://pending/placeholder.jpg";
|
||||
var bodyHtml = $"<p>Content</p><img src=\"{pendingUrl}\" alt=\"{image.Id}\" />";
|
||||
chapter.Body.Texts.Add(new LocalizationText
|
||||
{
|
||||
Language = Language.En,
|
||||
Text = bodyHtml
|
||||
});
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var adapter = Substitute.For<ISourceAdapter>();
|
||||
var eventBus = Substitute.For<IEventBus>();
|
||||
var service = CreateService(dbContext, adapter, eventBus, pendingUrl);
|
||||
|
||||
var newUrl = "https://cdn.example.com/uploaded/image.jpg";
|
||||
|
||||
// Act
|
||||
await service.UpdateImage(image.Id, newUrl);
|
||||
|
||||
// Assert
|
||||
var updatedImage = await dbContext.Images
|
||||
.Include(i => i.Chapter)
|
||||
.ThenInclude(c => c.Body)
|
||||
.ThenInclude(b => b.Texts)
|
||||
.FirstAsync(i => i.Id == image.Id);
|
||||
|
||||
updatedImage.NewPath.Should().Be(newUrl);
|
||||
|
||||
var updatedBodyText = updatedImage.Chapter!.Body.Texts.Single().Text;
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(updatedBodyText);
|
||||
var imgNode = doc.DocumentNode.SelectSingleNode("//img");
|
||||
imgNode.Should().NotBeNull();
|
||||
imgNode!.GetAttributeValue("src", string.Empty).Should().Be(newUrl);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateImage_does_not_modify_other_images_in_chapter_body()
|
||||
{
|
||||
// Arrange
|
||||
using var dbContext = CreateDbContext();
|
||||
var source = new Source { Name = "Demo", Key = "demo", Url = "http://demo" };
|
||||
var (novel, chapter) = CreateNovelWithSingleChapter(dbContext, source);
|
||||
|
||||
var image1 = new Image { OriginalPath = "http://original/img1.jpg", Chapter = chapter };
|
||||
var image2 = new Image { OriginalPath = "http://original/img2.jpg", Chapter = chapter };
|
||||
chapter.Images.Add(image1);
|
||||
chapter.Images.Add(image2);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var pendingUrl = "https://pending/placeholder.jpg";
|
||||
var bodyHtml = $"<p>Content</p><img src=\"{pendingUrl}\" alt=\"{image1.Id}\" /><img src=\"{pendingUrl}\" alt=\"{image2.Id}\" />";
|
||||
chapter.Body.Texts.Add(new LocalizationText
|
||||
{
|
||||
Language = Language.En,
|
||||
Text = bodyHtml
|
||||
});
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var adapter = Substitute.For<ISourceAdapter>();
|
||||
var eventBus = Substitute.For<IEventBus>();
|
||||
var service = CreateService(dbContext, adapter, eventBus, pendingUrl);
|
||||
|
||||
var newUrl = "https://cdn.example.com/uploaded/img1.jpg";
|
||||
|
||||
// Act - only update image1
|
||||
await service.UpdateImage(image1.Id, newUrl);
|
||||
|
||||
// Assert
|
||||
var updatedChapter = await dbContext.Chapters
|
||||
.Include(c => c.Body)
|
||||
.ThenInclude(b => b.Texts)
|
||||
.FirstAsync(c => c.Id == chapter.Id);
|
||||
|
||||
var updatedBodyText = updatedChapter.Body.Texts.Single().Text;
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(updatedBodyText);
|
||||
|
||||
var img1Node = doc.DocumentNode.SelectSingleNode($"//img[@alt='{image1.Id}']");
|
||||
var img2Node = doc.DocumentNode.SelectSingleNode($"//img[@alt='{image2.Id}']");
|
||||
|
||||
img1Node!.GetAttributeValue("src", string.Empty).Should().Be(newUrl);
|
||||
img2Node!.GetAttributeValue("src", string.Empty).Should().Be(pendingUrl);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user