diff --git a/Epsilon.Tests/Epsilon.Tests.csproj b/Epsilon.Tests/Epsilon.Tests.csproj index 4f96604d..f23c3c35 100644 --- a/Epsilon.Tests/Epsilon.Tests.csproj +++ b/Epsilon.Tests/Epsilon.Tests.csproj @@ -33,4 +33,8 @@ + + + + diff --git a/Epsilon.Tests/Exporters/WordModuleExporterTests.cs b/Epsilon.Tests/Exporters/WordModuleExporterTests.cs deleted file mode 100644 index 9350a4ee..00000000 --- a/Epsilon.Tests/Exporters/WordModuleExporterTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -using DocumentFormat.OpenXml.Packaging; -using Epsilon.Abstractions.Model; -using Epsilon.Export.Exporters; - -namespace Epsilon.Tests.Exporters; - -public class WordModuleExporterTests -{ - [Fact] - public async Task GivenExportData_WhenExportToWord_ThenFileShouldContainExportData() - { - // Arrange - var data = new ExportData - { - CourseModules = new List - { - new CourseModulePackage - { - Name = "Module 1", - Outcomes = new List - { - new CourseOutcome - { - Name = "Outcome 1", - Description = "Short Description", - Assignments = new List - { - new CourseAssignment - { - Name = "Assignment 1", - Url = new Uri("https://assignment1.com/"), - Score = "Good", - }, - new CourseAssignment - { - Name = "Assignment 2", - Url = new Uri("https://assignment2.com/"), - Score = "Outstanding", - }, - }, - }, - }, - }, - }, - }; - - var moduleExporter = new WordModuleExporter(); - - // Act - await using var stream = await moduleExporter.Export(data, "word"); - using var document = WordprocessingDocument.Open(stream, false); - - var content = document.MainDocumentPart?.Document.Body?.InnerText; - - // Assert - Assert.Contains("Module 1", content, StringComparison.InvariantCulture); - Assert.Contains("Outcome 1", content, StringComparison.InvariantCulture); - Assert.Contains("Short Description", content, StringComparison.InvariantCulture); - Assert.Contains("Assignment 1", content, StringComparison.InvariantCulture); - Assert.Contains("Assignment 2", content, StringComparison.InvariantCulture); - } -} \ No newline at end of file diff --git a/Epsilon/Export/Exporters/WordModuleExporter.cs b/Epsilon/Export/Exporters/WordModuleExporter.cs index 1e28e76a..83d0c26d 100644 --- a/Epsilon/Export/Exporters/WordModuleExporter.cs +++ b/Epsilon/Export/Exporters/WordModuleExporter.cs @@ -5,36 +5,38 @@ using DocumentFormat.OpenXml.Wordprocessing; using Epsilon.Abstractions.Export; using Epsilon.Abstractions.Model; +using Epsilon.Canvas.Abstractions.Service; using HtmlAgilityPack; namespace Epsilon.Export.Exporters; public class WordModuleExporter : ICanvasModuleExporter { + private readonly IFileHttpService _fileService; + + public WordModuleExporter(IFileHttpService fileService) + { + _fileService = fileService; + } + private static readonly TableBorders s_defaultBorders = new TableBorders(new TopBorder { - Val = new EnumValue(BorderValues.Single), - Size = 3, + Val = new EnumValue(BorderValues.Single), Size = 3, }, new BottomBorder { - Val = new EnumValue(BorderValues.Single), - Size = 3, + Val = new EnumValue(BorderValues.Single), Size = 3, }, new LeftBorder { - Val = new EnumValue(BorderValues.Single), - Size = 3, + Val = new EnumValue(BorderValues.Single), Size = 3, }, new RightBorder { - Val = new EnumValue(BorderValues.Single), - Size = 3, + Val = new EnumValue(BorderValues.Single), Size = 3, }, new InsideHorizontalBorder { - Val = new EnumValue(BorderValues.Single), - Size = 6, + Val = new EnumValue(BorderValues.Single), Size = 6, }, new InsideVerticalBorder { - Val = new EnumValue(BorderValues.Single), - Size = 6, + Val = new EnumValue(BorderValues.Single), Size = 6, }); private static readonly TableProperties s_defaultTableProperties = new TableProperties(s_defaultBorders); @@ -63,8 +65,7 @@ public async Task Export(ExportData data, string format) const string altChunkId = "HomePage"; - var personaHtml = new HtmlDocument(); - personaHtml.LoadHtml(data.PersonaHtml); + var personaHtml = await GetPersonaHtmlDocument(_fileService, data.PersonaHtml); using var ms = new MemoryStream(new UTF8Encoding(true).GetPreamble() .Concat(Encoding.UTF8.GetBytes($"{personaHtml.Text}")).ToArray()); @@ -138,4 +139,32 @@ private static TableCell CreateTextCell(string text) Type = TableWidthUnitValues.Auto, })); } + + private static async Task GetPersonaHtmlDocument(IFileHttpService fileService, string htmlString) + { + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(htmlString); + if (htmlDoc.DocumentNode.SelectNodes("//img") == null) + { + return null; + } + + foreach (var node in htmlDoc.DocumentNode.SelectNodes("//img")) + { + var imageSrc = node + .SelectNodes("//img") + .First() + .Attributes["src"].Value; + + if (imageSrc != null) + { + var imageBytes = await fileService.GetFileByteArray(new Uri(imageSrc)); + var imageBase64 = Convert.ToBase64String(imageBytes.ToArray()); + + node.SetAttributeValue("src", $"data:image/jpeg;base64,{imageBase64}"); + } + } + + return htmlDoc; + } } \ No newline at end of file