This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user