From 212c43915e11a8aa6860f324c809cf7af1a63352 Mon Sep 17 00:00:00 2001 From: Dev Date: Wed, 8 Apr 2026 14:34:45 +0200 Subject: [PATCH] feat(11-01): add ReportBranding model and BrandingHtmlHelper with tests - Add ReportBranding positional record bundling MspLogo and ClientLogo - Add BrandingHtmlHelper static class generating flex branding header HTML - Add BrandingHtmlHelperTests covering all 4 logo states (null, both null, single, both) - Add InternalsVisibleTo for SharepointToolbox.Tests in project file --- .../Export/BrandingHtmlHelperTests.cs | 105 ++++++++++++++++++ .../Core/Models/ReportBranding.cs | 8 ++ .../Services/Export/BrandingHtmlHelper.cs | 37 ++++++ SharepointToolbox/SharepointToolbox.csproj | 6 + 4 files changed, 156 insertions(+) create mode 100644 SharepointToolbox.Tests/Services/Export/BrandingHtmlHelperTests.cs create mode 100644 SharepointToolbox/Core/Models/ReportBranding.cs create mode 100644 SharepointToolbox/Services/Export/BrandingHtmlHelper.cs diff --git a/SharepointToolbox.Tests/Services/Export/BrandingHtmlHelperTests.cs b/SharepointToolbox.Tests/Services/Export/BrandingHtmlHelperTests.cs new file mode 100644 index 0000000..b017201 --- /dev/null +++ b/SharepointToolbox.Tests/Services/Export/BrandingHtmlHelperTests.cs @@ -0,0 +1,105 @@ +using SharepointToolbox.Core.Models; +using SharepointToolbox.Services.Export; +using Xunit; + +namespace SharepointToolbox.Tests.Services.Export; + +[Trait("Category", "Unit")] +public class BrandingHtmlHelperTests +{ + private static LogoData MakeLogo(string mime = "image/png", string base64 = "dGVzdA==") => + new() { MimeType = mime, Base64 = base64 }; + + // Test 1: null ReportBranding returns empty string + [Fact] + public void BuildBrandingHeader_NullBranding_ReturnsEmptyString() + { + var result = BrandingHtmlHelper.BuildBrandingHeader(null); + Assert.Equal(string.Empty, result); + } + + // Test 2: both logos null returns empty string + [Fact] + public void BuildBrandingHeader_BothLogosNull_ReturnsEmptyString() + { + var branding = new ReportBranding(null, null); + var result = BrandingHtmlHelper.BuildBrandingHeader(branding); + Assert.Equal(string.Empty, result); + } + + // Test 3: only MspLogo — contains MSP img tag, no second img + [Fact] + public void BuildBrandingHeader_OnlyMspLogo_ReturnsHtmlWithOneImg() + { + var msp = MakeLogo("image/png", "bXNwbG9nbw=="); + var branding = new ReportBranding(msp, null); + var result = BrandingHtmlHelper.BuildBrandingHeader(branding); + + Assert.Contains("data:image/png;base64,bXNwbG9nbw==", result); + Assert.Single(result.Split(" +/// Bundles MSP and client logos for passing to export services. +/// Export services receive this as a simple DTO — they don't know +/// about IBrandingService or ProfileService. +/// +public record ReportBranding(LogoData? MspLogo, LogoData? ClientLogo); diff --git a/SharepointToolbox/Services/Export/BrandingHtmlHelper.cs b/SharepointToolbox/Services/Export/BrandingHtmlHelper.cs new file mode 100644 index 0000000..4b2b266 --- /dev/null +++ b/SharepointToolbox/Services/Export/BrandingHtmlHelper.cs @@ -0,0 +1,37 @@ +using System.Text; +using SharepointToolbox.Core.Models; + +namespace SharepointToolbox.Services.Export; + +/// +/// Generates the branding header HTML fragment for HTML reports. +/// Called by each HTML export service between <body> and <h1>. +/// Returns empty string when no logos are configured (no broken images). +/// +internal static class BrandingHtmlHelper +{ + public static string BuildBrandingHeader(ReportBranding? branding) + { + if (branding is null) return string.Empty; + + var msp = branding.MspLogo; + var client = branding.ClientLogo; + + if (msp is null && client is null) return string.Empty; + + var sb = new StringBuilder(); + sb.AppendLine("
"); + + if (msp is not null) + sb.AppendLine($" \"\""); + + if (msp is not null && client is not null) + sb.AppendLine("
"); + + if (client is not null) + sb.AppendLine($" \"\""); + + sb.AppendLine("
"); + return sb.ToString(); + } +} diff --git a/SharepointToolbox/SharepointToolbox.csproj b/SharepointToolbox/SharepointToolbox.csproj index c068ecd..b919de1 100644 --- a/SharepointToolbox/SharepointToolbox.csproj +++ b/SharepointToolbox/SharepointToolbox.csproj @@ -18,6 +18,12 @@ true + + + <_Parameter1>SharepointToolbox.Tests + + +