UX Overhaul Part 1 (#3047)
Co-authored-by: Joseph Milazzo <joseph.v.milazzo@gmail.com>
|
@ -6,13 +6,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageReference Include="NSubstitute" Version="5.1.0" />
|
||||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.22" />
|
||||
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="21.0.22" />
|
||||
<PackageReference Include="xunit" Version="2.8.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
|
||||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.29" />
|
||||
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="21.0.29" />
|
||||
<PackageReference Include="xunit" Version="2.9.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using API.Entities.Enums;
|
||||
using API.Services;
|
||||
using EasyCaching.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NetVips;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
using Image = NetVips.Image;
|
||||
|
||||
|
@ -12,6 +17,7 @@ namespace API.Tests.Services;
|
|||
public class ImageServiceTests
|
||||
{
|
||||
private readonly string _testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ImageService/Covers");
|
||||
private readonly string _testDirectoryColorScapes = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ImageService/ColorScapes");
|
||||
private const string OutputPattern = "_output";
|
||||
private const string BaselinePattern = "_baseline";
|
||||
|
||||
|
@ -121,4 +127,98 @@ public class ImageServiceTests
|
|||
File.WriteAllText(Path.Combine(_testDirectory, "index.html"), htmlBuilder.ToString());
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TestColorScapes()
|
||||
{
|
||||
// Step 1: Delete any images that have _output in the name
|
||||
var outputFiles = Directory.GetFiles(_testDirectoryColorScapes, "*_output.*");
|
||||
foreach (var file in outputFiles)
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
// Step 2: Scan the _testDirectory for images
|
||||
var imageFiles = Directory.GetFiles(_testDirectoryColorScapes, "*.*")
|
||||
.Where(file => !file.EndsWith("html"))
|
||||
.Where(file => !file.Contains(OutputPattern) && !file.Contains(BaselinePattern))
|
||||
.ToList();
|
||||
|
||||
// Step 3: Process each image
|
||||
foreach (var imagePath in imageFiles)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(imagePath);
|
||||
var colors = ImageService.CalculateColorScape(imagePath);
|
||||
|
||||
// Generate primary color image
|
||||
GenerateColorImage(colors.Primary, Path.Combine(_testDirectoryColorScapes, $"{fileName}_primary_output.png"));
|
||||
|
||||
// Generate secondary color image
|
||||
GenerateColorImage(colors.Secondary, Path.Combine(_testDirectoryColorScapes, $"{fileName}_secondary_output.png"));
|
||||
}
|
||||
|
||||
// Step 4: Generate HTML file
|
||||
GenerateHtmlFileForColorScape();
|
||||
|
||||
}
|
||||
|
||||
private static void GenerateColorImage(string hexColor, string outputPath)
|
||||
{
|
||||
var color = ImageService.HexToRgb(hexColor);
|
||||
using var colorImage = Image.Black(200, 100);
|
||||
using var output = colorImage + new[] { color.R / 255.0, color.G / 255.0, color.B / 255.0 };
|
||||
output.WriteToFile(outputPath);
|
||||
}
|
||||
|
||||
private void GenerateHtmlFileForColorScape()
|
||||
{
|
||||
var imageFiles = Directory.GetFiles(_testDirectoryColorScapes, "*.*")
|
||||
.Where(file => !file.EndsWith("html"))
|
||||
.Where(file => !file.Contains(OutputPattern) && !file.Contains(BaselinePattern))
|
||||
.ToList();
|
||||
|
||||
var htmlBuilder = new StringBuilder();
|
||||
htmlBuilder.AppendLine("<!DOCTYPE html>");
|
||||
htmlBuilder.AppendLine("<html lang=\"en\">");
|
||||
htmlBuilder.AppendLine("<head>");
|
||||
htmlBuilder.AppendLine("<meta charset=\"UTF-8\">");
|
||||
htmlBuilder.AppendLine("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
|
||||
htmlBuilder.AppendLine("<title>Color Scape Comparison</title>");
|
||||
htmlBuilder.AppendLine("<style>");
|
||||
htmlBuilder.AppendLine("body { font-family: Arial, sans-serif; }");
|
||||
htmlBuilder.AppendLine(".container { display: flex; flex-wrap: wrap; }");
|
||||
htmlBuilder.AppendLine(".image-row { display: flex; align-items: center; margin-bottom: 20px; width: 100% }");
|
||||
htmlBuilder.AppendLine(".image-row img { margin-right: 10px; max-width: 200px; height: auto; }");
|
||||
htmlBuilder.AppendLine(".color-square { width: 100px; height: 100px; margin-right: 10px; }");
|
||||
htmlBuilder.AppendLine("</style>");
|
||||
htmlBuilder.AppendLine("</head>");
|
||||
htmlBuilder.AppendLine("<body>");
|
||||
htmlBuilder.AppendLine("<div class=\"container\">");
|
||||
|
||||
foreach (var imagePath in imageFiles)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(imagePath);
|
||||
var primaryPath = Path.Combine(_testDirectoryColorScapes, $"{fileName}_primary_output.png");
|
||||
var secondaryPath = Path.Combine(_testDirectoryColorScapes, $"{fileName}_secondary_output.png");
|
||||
|
||||
htmlBuilder.AppendLine("<div class=\"image-row\">");
|
||||
htmlBuilder.AppendLine($"<p>{fileName}</p>");
|
||||
htmlBuilder.AppendLine($"<img src=\"./{Path.GetFileName(imagePath)}\" alt=\"{fileName}\">");
|
||||
if (File.Exists(primaryPath))
|
||||
{
|
||||
htmlBuilder.AppendLine($"<img class=\"color-square\" src=\"./{Path.GetFileName(primaryPath)}\" alt=\"{fileName} primary color\">");
|
||||
}
|
||||
if (File.Exists(secondaryPath))
|
||||
{
|
||||
htmlBuilder.AppendLine($"<img class=\"color-square\" src=\"./{Path.GetFileName(secondaryPath)}\" alt=\"{fileName} secondary color\">");
|
||||
}
|
||||
htmlBuilder.AppendLine("</div>");
|
||||
}
|
||||
|
||||
htmlBuilder.AppendLine("</div>");
|
||||
htmlBuilder.AppendLine("</body>");
|
||||
htmlBuilder.AppendLine("</html>");
|
||||
|
||||
File.WriteAllText(Path.Combine(_testDirectoryColorScapes, "colorscape_index.html"), htmlBuilder.ToString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,9 @@ public class ReadingListServiceTests
|
|||
var mapper = config.CreateMapper();
|
||||
_unitOfWork = new UnitOfWork(_context, mapper, null!);
|
||||
|
||||
_readingListService = new ReadingListService(_unitOfWork, Substitute.For<ILogger<ReadingListService>>(), Substitute.For<IEventHub>());
|
||||
var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), new MockFileSystem());
|
||||
_readingListService = new ReadingListService(_unitOfWork, Substitute.For<ILogger<ReadingListService>>(),
|
||||
Substitute.For<IEventHub>(), Substitute.For<IImageService>(), ds);
|
||||
|
||||
_readerService = new ReaderService(_unitOfWork, Substitute.For<ILogger<ReaderService>>(),
|
||||
Substitute.For<IEventHub>(), Substitute.For<IImageService>(),
|
||||
|
|
BIN
API.Tests/Services/Test Data/ImageService/ColorScapes/blue-2.png
Normal file
After Width: | Height: | Size: 336 KiB |
BIN
API.Tests/Services/Test Data/ImageService/ColorScapes/blue.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 320 KiB |
BIN
API.Tests/Services/Test Data/ImageService/ColorScapes/green.png
Normal file
After Width: | Height: | Size: 340 KiB |
After Width: | Height: | Size: 294 KiB |
After Width: | Height: | Size: 286 KiB |
BIN
API.Tests/Services/Test Data/ImageService/ColorScapes/pink.png
Normal file
After Width: | Height: | Size: 327 KiB |
After Width: | Height: | Size: 168 KiB |