using FluentAssertions; using FreeCode.State; using FreeCode.Tasks; using Xunit; using TaskStatus = FreeCode.Core.Enums.TaskStatus; namespace FreeCode.Tests.Integration; public sealed class StateFlowTests { [Fact] public async Task BackgroundTaskManager_UpdatesAppStateStore_TaskCollection() { var store = new AppStateStore(); await using var manager = new BackgroundTaskManager(store); var psi = new System.Diagnostics.ProcessStartInfo { FileName = "/bin/zsh", Arguments = "-lc \"printf state-flow\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; var task = await manager.CreateShellTaskAsync("printf state-flow", psi); await WaitUntilAsync(() => store.GetTypedState().Tasks.ContainsKey(task.TaskId), TimeSpan.FromSeconds(5)); await WaitUntilAsync(() => store.GetTypedState().Tasks[task.TaskId].Status is TaskStatus.Completed or TaskStatus.Failed, TimeSpan.FromSeconds(5)); store.GetTypedState().Tasks.Should().ContainKey(task.TaskId); store.GetTypedState().Tasks[task.TaskId].Status.Should().Be(TaskStatus.Completed); } private static async Task WaitUntilAsync(Func condition, TimeSpan timeout) { var deadline = DateTime.UtcNow + timeout; while (DateTime.UtcNow < deadline) { if (condition()) { return; } await Task.Delay(50); } throw new TimeoutException("Condition was not met before timeout."); } }