using System.Net; using AngleSharp.Dom; using Bit.Icons.Models; using Bit.Icons.Services; using Microsoft.Extensions.Logging; using NSubstitute; using Xunit; namespace Bit.Icons.Test.Models; public class IconLinkTests { private readonly IElement _element; private readonly Uri _uri = new("https://icon.test"); private readonly ILogger _logger = Substitute.For>(); private readonly IHttpClientFactory _httpClientFactory; private readonly IUriService _uriService; private readonly string _baseUrlPath = "/"; public IconLinkTests() { _element = Substitute.For(); _httpClientFactory = Substitute.For(); _uriService = Substitute.For(); _uriService.TryGetUri(Arg.Any(), out Arg.Any()).Returns(x => { x[1] = new IconUri(new Uri("https://icon.test"), IPAddress.Parse("192.0.2.1")); return true; }); } [Fact] public void WithNoHref_IsNotUsable() { _element.GetAttribute("href").Returns(string.Empty); var result = new IconLink(_element, _uri, _baseUrlPath).IsUsable(); Assert.False(result); } [Theory] [InlineData(null, false)] [InlineData("", false)] [InlineData(" ", false)] [InlineData("unusable", false)] [InlineData("ico", true)] public void WithNoRel_IsUsable(string extension, bool expectedResult) { SetAttributeValue("href", $"/favicon.{extension}"); var result = new IconLink(_element, _uri, _baseUrlPath).IsUsable(); Assert.Equal(expectedResult, result); } [Theory] [InlineData("icon", true)] [InlineData("stylesheet", false)] public void WithRel_IsUsable(string rel, bool expectedResult) { SetAttributeValue("href", "/favicon.ico"); SetAttributeValue("rel", rel); var result = new IconLink(_element, _uri, _baseUrlPath).IsUsable(); Assert.Equal(expectedResult, result); } [Fact] public async Task FetchAsync_Unvalidated_ReturnsNull() { var result = await new IconLink(_element, _uri, _baseUrlPath).FetchAsync(_logger, _httpClientFactory, _uriService); Assert.Null(result); } private void SetAttributeValue(string attribute, string value) { var attr = Substitute.For(); attr.Value.Returns(value); _element.Attributes[attribute].Returns(attr); } }