feat: harden isolated Tornado test workflow

This commit is contained in:
2026-07-10 11:27:40 +09:00
parent 5a8c7028dc
commit fc932b27f6
36 changed files with 3919 additions and 226 deletions

View File

@@ -0,0 +1,87 @@
using System.Text.Json;
using MBN_STOCK_WEBVIEW.Core.Playout;
namespace MBN_STOCK_WEBVIEW.Core.Tests;
public sealed class PlayoutBridgeProtocolTests
{
[Theory]
[InlineData("https://app.mbn.local/index.html", true)]
[InlineData("HTTPS://APP.MBN.LOCAL/path", true)]
[InlineData("http://app.mbn.local/index.html", false)]
[InlineData("https://app.mbn.local:444/index.html", false)]
[InlineData("https://app.mbn.local@evil.example/index.html", false)]
[InlineData("https://evil.example/index.html", false)]
[InlineData("about:blank", false)]
[InlineData("not-a-uri", false)]
public void IsTrustedSource_RequiresTheExactHttpsDefaultPortOrigin(
string source,
bool expected)
{
Assert.Equal(
expected,
PlayoutBridgeProtocol.IsTrustedSource(source, "app.mbn.local"));
}
[Theory]
[InlineData("prepare", true)]
[InlineData("next", true)]
[InlineData("take-in", false)]
[InlineData("take-out", false)]
public void ParseCommand_AcceptsOnlyTheCommandSpecificCueShape(
string command,
bool hasCue)
{
var cue = hasCue ? ",\"cue\":{\"code\":\"5001\"}" : string.Empty;
using var document = JsonDocument.Parse(
$"{{\"requestId\":\"REQ_1\",\"command\":\"{command}\"{cue}}}");
var result = PlayoutBridgeProtocol.ParseCommand(document.RootElement);
Assert.True(result.IsValid);
Assert.Equal("REQ_1", result.Request.RequestId);
Assert.Equal(command, result.Request.Command);
if (hasCue)
{
Assert.Equal("5001", result.Request.Cue?.SceneName);
Assert.Equal("5001.t2s", result.Request.Cue?.SceneFile);
}
else
{
Assert.Null(result.Request.Cue);
}
}
[Theory]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"prepare\",\"cue\":{\"code\":\"../5001\"}}")]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"prepare\",\"cue\":{\"code\":\"5001\",\"title\":\"ignored\"}}")]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"take-in\",\"cue\":{\"code\":\"5001\"}}")]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"next\"}")]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"unknown\"}")]
[InlineData("{\"requestId\":\"REQ\",\"requestId\":\"REQ2\",\"command\":\"take-out\"}")]
[InlineData("{\"requestId\":\"REQ\",\"command\":\"take-out\",\"liveAuthorization\":true}")]
public void ParseCommand_RejectsUnknownDuplicateOrUnsafeInput(string json)
{
using var document = JsonDocument.Parse(json);
var result = PlayoutBridgeProtocol.ParseCommand(document.RootElement);
Assert.False(result.IsValid);
Assert.NotEmpty(result.Error);
Assert.Null(result.Request.Cue);
}
[Fact]
public void ParseCommand_DoesNotReflectAnUnsafeRequestIdentifier()
{
const string unsafeRequestId = "../../private-value";
using var document = JsonDocument.Parse(
$"{{\"requestId\":\"{unsafeRequestId}\",\"command\":\"take-out\"}}");
var result = PlayoutBridgeProtocol.ParseCommand(document.RootElement);
Assert.False(result.IsValid);
Assert.Equal(string.Empty, result.Request.RequestId);
Assert.DoesNotContain(unsafeRequestId, result.Error, StringComparison.Ordinal);
}
}