Files
Dev 212c43915e 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
2026-04-08 14:34:45 +02:00

106 lines
3.9 KiB
C#

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("<img", StringSplitOptions.None).Skip(1).ToArray());
}
// Test 4: only ClientLogo — contains client img tag, no flex spacer div
[Fact]
public void BuildBrandingHeader_OnlyClientLogo_ReturnsHtmlWithOneImgNoSpacer()
{
var client = MakeLogo("image/jpeg", "Y2xpZW50bG9nbw==");
var branding = new ReportBranding(null, client);
var result = BrandingHtmlHelper.BuildBrandingHeader(branding);
Assert.Contains("data:image/jpeg;base64,Y2xpZW50bG9nbw==", result);
Assert.Single(result.Split("<img", StringSplitOptions.None).Skip(1).ToArray());
Assert.DoesNotContain("flex:1", result);
}
// Test 5: both logos — two img tags and a flex spacer div between them
[Fact]
public void BuildBrandingHeader_BothLogos_ReturnsHtmlWithTwoImgsAndSpacer()
{
var msp = MakeLogo("image/png", "bXNw");
var client = MakeLogo("image/jpeg", "Y2xpZW50");
var branding = new ReportBranding(msp, client);
var result = BrandingHtmlHelper.BuildBrandingHeader(branding);
Assert.Contains("data:image/png;base64,bXNw", result);
Assert.Contains("data:image/jpeg;base64,Y2xpZW50", result);
Assert.Equal(2, result.Split("<img", StringSplitOptions.None).Length - 1);
Assert.Contains("flex:1", result);
}
// Test 6: img tags use inline data-URI format
[Fact]
public void BuildBrandingHeader_WithMspLogo_UsesDataUriFormat()
{
var msp = MakeLogo("image/png", "dGVzdA==");
var branding = new ReportBranding(msp, null);
var result = BrandingHtmlHelper.BuildBrandingHeader(branding);
Assert.Contains("src=\"data:image/png;base64,dGVzdA==\"", result);
}
// Test 7: img tags have max-height:60px and max-width:200px styles
[Fact]
public void BuildBrandingHeader_WithLogo_ImgHasCorrectDimensions()
{
var msp = MakeLogo();
var branding = new ReportBranding(msp, null);
var result = BrandingHtmlHelper.BuildBrandingHeader(branding);
Assert.Contains("max-height:60px", result);
Assert.Contains("max-width:200px", result);
}
// Test 8: outer div uses display:flex;gap:16px;align-items:center
[Fact]
public void BuildBrandingHeader_WithLogo_OuterDivUsesFlexLayout()
{
var msp = MakeLogo();
var branding = new ReportBranding(msp, null);
var result = BrandingHtmlHelper.BuildBrandingHeader(branding);
Assert.Contains("display:flex", result);
Assert.Contains("gap:16px", result);
Assert.Contains("align-items:center", result);
}
}