using System.Net; using AngleSharp.Html.Parser; using Bit.Icons.Models; using Bit.Icons.Services; using Bit.Test.Common.Helpers; using Bit.Test.Common.MockedHttpClient; using Microsoft.Extensions.Logging.Abstractions; using NSubstitute; using Xunit; namespace Bit.Icons.Test.Models; public class IconHttpResponseTests { private readonly IUriService _mockedUriService; private static readonly IHtmlParser _parser = new HtmlParser(); public IconHttpResponseTests() { _mockedUriService = Substitute.For(); _mockedUriService.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 async Task RetrieveIconsAsync_Processes200LinksAsync() { var htmlBuilder = new HtmlBuilder(); var headBuilder = new HtmlBuilder("head"); for (var i = 0; i < 200; i++) { headBuilder.Append(UnusableLinkNode()); } headBuilder.Append(UsableLinkNode()); htmlBuilder.Append(headBuilder); var response = GetHttpResponseMessage(htmlBuilder.ToString()); var sut = CurriedIconHttpResponse()(response); var result = await sut.RetrieveIconsAsync(new Uri("https://icon.test"), "icon.test", _parser); Assert.Empty(result); } [Fact] public async Task RetrieveIconsAsync_Processes10IconsAsync() { var htmlBuilder = new HtmlBuilder(); var headBuilder = new HtmlBuilder("head"); for (var i = 0; i < 11; i++) { headBuilder.Append(UsableLinkNode()); } htmlBuilder.Append(headBuilder); var response = GetHttpResponseMessage(htmlBuilder.ToString()); var sut = CurriedIconHttpResponse()(response); var result = await sut.RetrieveIconsAsync(new Uri("https://icon.test"), "icon.test", _parser); Assert.Equal(10, result.Count()); } private static string UsableLinkNode() { return ""; } private static string UnusableLinkNode() { // Empty href links are not usable return ""; } private static HttpResponseMessage GetHttpResponseMessage(string content) { return new HttpResponseMessage(HttpStatusCode.OK) { RequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://icon.test"), Content = new StringContent(content) }; } private Func CurriedIconHttpResponse() { return (HttpResponseMessage response) => new IconHttpResponse(response, NullLogger.Instance, UsableIconHttpClientFactory(), _mockedUriService); } private static IHttpClientFactory UsableIconHttpClientFactory() { var substitute = Substitute.For(); var handler = new MockedHttpMessageHandler(); handler.Fallback .WithStatusCode(HttpStatusCode.OK) .WithContent("image/png", new byte[] { 137, 80, 78, 71 }); substitute.CreateClient("Icons").Returns(handler.ToHttpClient()); return substitute; } }