| File: WorkflowScripts\DeploymentTestCommandTests.cs | Web Access |
| Project: src\tests\Infrastructure.Tests\Infrastructure.Tests.csproj (Infrastructure.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.TestUtilities; using Xunit; using YamlDotNet.RepresentationModel; namespace Infrastructure.Tests; public sealed class DeploymentTestCommandTests(ITestOutputHelper output) { [Fact] public void DeploymentStepsRequireRepositoryWriteAccess() { var steps = LoadSteps(); Assert.Equal("check_permission", Scalar(steps[0], "id")); Assert.Equal(3, steps.Length); foreach (var step in steps.Skip(1)) { Assert.Equal("steps.check_permission.outputs.has_write_access == 'true'", Scalar(step, "if")); } } [Theory] [InlineData("write")] [InlineData("admin")] [InlineData("maintain")] [InlineData("read")] [InlineData("triage")] [InlineData("none")] [InlineData("unknown")] [InlineData("error-403")] [InlineData("error-404")] [InlineData("error-500")] [RequiresTools(["node"])] public async Task PermissionCheckOnlyAllowsRepositoryWriters(string scenario) => await RunPermissionCheckAsync(scenario, "/deployment-test", validCommand: true); [Theory] [InlineData("/deployment-test", true)] [InlineData("/deployment-test ", true)] [InlineData("/deployment-test arguments", true)] [InlineData("/deployment-test\n", true)] [InlineData("/deployment-test\r", true)] [InlineData("/deployment-test\r\nMore text", true)] [InlineData("/deployment-test\targuments", true)] [InlineData("/DEPLOYMENT-TEST\nMore text", true)] [InlineData("/deployment-testing", false)] [InlineData("/deployment-test-disabled", false)] [InlineData("/deployment-test/extra", false)] [InlineData("/deployment-test.", false)] [InlineData(" /deployment-test", false)] [InlineData("Please run /deployment-test", false)] [InlineData("", false)] [RequiresTools(["node"])] public async Task CommandRequiresEndOfTextOrWhitespace(string body, bool validCommand) => await RunPermissionCheckAsync("write", body, validCommand); private async Task RunPermissionCheckAsync(string scenario, string body, bool validCommand) { using var workspace = TemporaryWorkspace.Create(output); var options = Assert.IsType<YamlMappingNode>(LoadSteps()[0].Children[new YamlScalarNode("with")]); var scriptPath = Path.Combine(workspace.Path, "permission-check.js"); await File.WriteAllTextAsync(scriptPath, Scalar(options, "script")); using var node = new NodeCommand(output, nameof(DeploymentTestCommandTests)) .WithTimeout(TimeSpan.FromMinutes(1)); var result = await node.ExecuteScriptAsync( Path.Combine(RepoRoot.Path, "tests", "Infrastructure.Tests", "WorkflowScripts", "deployment-test-command.harness.mjs"), scriptPath, scenario, body, validCommand ? "true" : "false"); Assert.True(result.ExitCode == 0, result.Output); } private static YamlMappingNode[] LoadSteps() { var steps = Assert.IsType<YamlSequenceNode>(LoadJob().Children[new YamlScalarNode("steps")]); return steps.Children.Select(Assert.IsType<YamlMappingNode>).ToArray(); } private static YamlMappingNode LoadJob() { using var reader = File.OpenText(Path.Combine(RepoRoot.Path, ".github", "workflows", "deployment-test-command.yml")); var yaml = new YamlStream(); yaml.Load(reader); var root = Assert.IsType<YamlMappingNode>(yaml.Documents[0].RootNode); var jobs = Assert.IsType<YamlMappingNode>(root.Children[new YamlScalarNode("jobs")]); return Assert.IsType<YamlMappingNode>(jobs.Children[new YamlScalarNode("deployment-test")]); } private static string Scalar(YamlMappingNode node, string key) => Assert.IsType<YamlScalarNode>(node.Children[new YamlScalarNode(key)]).Value!; }