130 lines
4.5 KiB
C#
130 lines
4.5 KiB
C#
using System.Net;
|
|
using YMhut.Box.Core.Media;
|
|
|
|
namespace YMhut.Box.Tests;
|
|
|
|
[TestClass]
|
|
public sealed class RemoteMediaResolverTests
|
|
{
|
|
[TestMethod]
|
|
public async Task ResolvesRedirectToDirectMedia()
|
|
{
|
|
var resolver = CreateResolver(request =>
|
|
{
|
|
if (request.RequestUri?.AbsolutePath == "/api")
|
|
{
|
|
return Redirect("/media/demo.mp4");
|
|
}
|
|
|
|
return Text(HttpStatusCode.OK, string.Empty, "video/mp4");
|
|
});
|
|
|
|
var result = await resolver.ResolveMediaAsync("https://example.test/api", RemoteMediaKind.Video, cacheBust: false);
|
|
|
|
Assert.AreEqual("https://example.test/media/demo.mp4", result.Uri.AbsoluteUri);
|
|
Assert.IsTrue(result.IsDirectMedia);
|
|
Assert.AreEqual("video/mp4", result.ContentType);
|
|
Assert.AreEqual(".mp4", result.SuggestedExtension);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ExtractsPlainTextUrl()
|
|
{
|
|
var resolver = CreateResolver(request =>
|
|
{
|
|
if (request.RequestUri?.Host == "cdn.test")
|
|
{
|
|
return Text(HttpStatusCode.OK, string.Empty, "video/mp4");
|
|
}
|
|
|
|
return Text(HttpStatusCode.OK, "https://cdn.test/random/clip.mp4", "text/plain");
|
|
});
|
|
|
|
var result = await resolver.ResolveMediaAsync("https://example.test/api", RemoteMediaKind.Video, cacheBust: false);
|
|
|
|
Assert.AreEqual("https://cdn.test/random/clip.mp4", result.Uri.AbsoluteUri);
|
|
Assert.IsTrue(result.IsDirectMedia);
|
|
Assert.AreEqual(".mp4", result.SuggestedExtension);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ExtractsNestedJsonUrl()
|
|
{
|
|
var resolver = CreateResolver(request =>
|
|
{
|
|
if (request.RequestUri?.Host == "cdn.test")
|
|
{
|
|
return Text(HttpStatusCode.OK, string.Empty, "image/webp");
|
|
}
|
|
|
|
return Text(HttpStatusCode.OK, """
|
|
{
|
|
"data": {
|
|
"url": "https://cdn.test/images/pic.webp"
|
|
}
|
|
}
|
|
""", "application/json");
|
|
});
|
|
|
|
var result = await resolver.ResolveMediaAsync("https://example.test/api", RemoteMediaKind.Image, cacheBust: false);
|
|
|
|
Assert.AreEqual("https://cdn.test/images/pic.webp", result.Uri.AbsoluteUri);
|
|
Assert.IsTrue(result.IsDirectMedia);
|
|
Assert.AreEqual(".webp", result.SuggestedExtension);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task KeepsHtmlWithoutMediaUrlAsNonDirect()
|
|
{
|
|
var resolver = CreateResolver(_ => Text(HttpStatusCode.OK, "<html><body>No media here</body></html>", "text/html"));
|
|
|
|
var result = await resolver.ResolveMediaAsync("https://example.test/page", RemoteMediaKind.Video, cacheBust: false);
|
|
|
|
Assert.AreEqual("https://example.test/page", result.Uri.AbsoluteUri);
|
|
Assert.IsFalse(result.IsDirectMedia);
|
|
Assert.AreEqual("text/html", result.ContentType);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TreatsDirectMediaContentTypeAsPlayable()
|
|
{
|
|
var resolver = CreateResolver(_ => Text(HttpStatusCode.OK, string.Empty, "audio/mpeg"));
|
|
|
|
var result = await resolver.ResolveMediaAsync("https://example.test/random", RemoteMediaKind.Audio, cacheBust: false);
|
|
|
|
Assert.AreEqual("https://example.test/random", result.Uri.AbsoluteUri);
|
|
Assert.IsTrue(result.IsDirectMedia);
|
|
Assert.AreEqual(".mp3", result.SuggestedExtension);
|
|
}
|
|
|
|
private static RemoteMediaResolver CreateResolver(Func<HttpRequestMessage, HttpResponseMessage> responseFactory)
|
|
{
|
|
return new RemoteMediaResolver(() => new StubHttpHandler(responseFactory));
|
|
}
|
|
|
|
private static HttpResponseMessage Redirect(string location)
|
|
{
|
|
var response = new HttpResponseMessage(HttpStatusCode.Redirect);
|
|
response.Headers.Location = new Uri(location, UriKind.RelativeOrAbsolute);
|
|
return response;
|
|
}
|
|
|
|
private static HttpResponseMessage Text(HttpStatusCode statusCode, string content, string contentType)
|
|
{
|
|
return new HttpResponseMessage(statusCode)
|
|
{
|
|
Content = new StringContent(content, System.Text.Encoding.UTF8, contentType)
|
|
};
|
|
}
|
|
|
|
private sealed class StubHttpHandler(Func<HttpRequestMessage, HttpResponseMessage> responseFactory) : HttpMessageHandler
|
|
{
|
|
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
{
|
|
var response = responseFactory(request);
|
|
response.RequestMessage = request;
|
|
return Task.FromResult(response);
|
|
}
|
|
}
|
|
}
|