using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging.Abstractions; using w4c_workflows.Controllers; using w4c_workflows.Data; using w4c_workflows.Models; using w4c_workflows.Services; using w4c_workflows.Services.Runs; using Xunit; namespace w4c_workflows.Tests; [Collection("WorkflowsPostgres")] public class WorkflowsControllerTriggerTests { private sealed class FakeWorkflowSource : IWorkflowSource { public Task> ListAsync(CancellationToken ct) => Task.FromResult>(Array.Empty()); public Task ReadAsync(string path, CancellationToken ct) => Task.FromResult(string.Empty); public WorkflowSourceState GetState() => new(null, false); } private readonly WorkflowsPostgresFixture _fixture; public WorkflowsControllerTriggerTests(WorkflowsPostgresFixture fixture) { _fixture = fixture; } private static WorkflowsController Controller(WorkflowsDbContext db, string tenantId) { var sync = new WorkflowSyncService( db, new WorkflowCompiler(new WorkflowValidator(new LanguageRegistry())), new FakeWorkflowSource(), NullLogger.Instance); var controller = new WorkflowsController( db, sync, new FakeWorkflowSource(), new MermaidGeneratorService(), new WorkflowHtmlRenderer(NullLogger.Instance), new RenderTokenService(new ConfigurationBuilder().Build(), NullLogger.Instance), new RunLauncher(db, NullLogger.Instance), new DurableStateStore(db), NullLogger.Instance) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() }, }; controller.HttpContext.Items["TenantId"] = tenantId; return controller; } [Fact] public async Task Toggle_disables_and_enables_the_trigger() { var tenantId = "t" + Guid.NewGuid().ToString("N")[..12]; await using var db = _fixture.CreateContext(); var workflow = WorkflowDataHelpers.CompileAndSave(db, tenantId, WorkflowDataHelpers.LinearYaml); Assert.True(workflow.TriggerEnabled); var controller = Controller(db, tenantId); var disable = Assert.IsType(await controller.SetTriggerEnabled(workflow.Id, "disable", default)); var disabled = Assert.IsType(disable.Value); Assert.False(disabled.TriggerEnabled); Assert.False((await db.Workflows.SingleAsync(w => w.Id == workflow.Id)).TriggerEnabled); var enable = Assert.IsType(await controller.SetTriggerEnabled(workflow.Id, "enable", default)); var enabled = Assert.IsType(enable.Value); Assert.True(enabled.TriggerEnabled); } [Fact] public async Task Toggle_rejects_unknown_action() { var tenantId = "t" + Guid.NewGuid().ToString("N")[..12]; await using var db = _fixture.CreateContext(); var workflow = WorkflowDataHelpers.CompileAndSave(db, tenantId, WorkflowDataHelpers.LinearYaml); var result = await Controller(db, tenantId).SetTriggerEnabled(workflow.Id, "pause", default); Assert.IsType(result); } [Fact] public async Task Toggle_404s_for_foreign_workflow() { var tenantId = "t" + Guid.NewGuid().ToString("N")[..12]; await using var db = _fixture.CreateContext(); var other = "t" + Guid.NewGuid().ToString("N")[..12]; var workflow = WorkflowDataHelpers.CompileAndSave(db, other, WorkflowDataHelpers.LinearYaml); var result = await Controller(db, tenantId).SetTriggerEnabled(workflow.Id, "disable", default); Assert.IsType(result); } }