using Nexus.Api.Data; using Xunit; namespace Nexus.Api.Tests; public class TaskBoardTests { // ── TaskStateHelper: BoardGroupKey ── [Theory] [InlineData("Backlog", "offen")] [InlineData("In progress", "inProgress")] [InlineData("Delegated", "delegated")] [InlineData("Review", "review")] [InlineData("Blocked", "blocked")] [InlineData("Done", "done")] [InlineData("backlog", "offen")] [InlineData("in progress", "inProgress")] [InlineData("delegated", "delegated")] [InlineData("review", "review")] [InlineData("blocked", "blocked")] [InlineData("done", "done")] [InlineData("", "offen")] [InlineData(null, "offen")] [InlineData("unknown", "offen")] public void BoardGroupKey_ReturnsExpectedGroup(string? state, string expected) { var result = TaskStateHelper.BoardGroupKey(state); Assert.Equal(expected, result); } // ── TaskStateHelper: BoardGroupToState ── [Theory] [InlineData("offen", "Backlog")] [InlineData("inProgress", "In progress")] [InlineData("inprogress", "In progress")] [InlineData("delegated", "Delegated")] [InlineData("review", "Review")] [InlineData("blocked", "Blocked")] [InlineData("done", "Done")] [InlineData("Offen", "Backlog")] [InlineData("", null)] [InlineData(null, null)] [InlineData("unknown", null)] public void BoardGroupToState_ReturnsExpectedState(string? groupKey, string? expected) { var result = TaskStateHelper.BoardGroupToState(groupKey); Assert.Equal(expected, result); } // ── TaskStateHelper: AllStates has 6 entries ── [Fact] public void AllStates_ContainsAllSixStates() { var states = TaskStateHelper.AllStates; Assert.Equal(6, states.Length); Assert.Contains("Backlog", states); Assert.Contains("In progress", states); Assert.Contains("Delegated", states); Assert.Contains("Review", states); Assert.Contains("Blocked", states); Assert.Contains("Done", states); } // ── TaskStateHelper: IsValidState ── [Theory] [InlineData("Backlog", true)] [InlineData("In progress", true)] [InlineData("Delegated", true)] [InlineData("Review", true)] [InlineData("Blocked", true)] [InlineData("Done", true)] [InlineData("backlog", true)] [InlineData("offen", false)] [InlineData("", false)] [InlineData(null, false)] [InlineData("unknown", false)] public void IsValidState_ReturnsCorrectResult(string? state, bool expected) { Assert.Equal(expected, TaskStateHelper.IsValidState(state)); } // ── TaskStateHelper: IsInProgressOrBlocked ── [Theory] [InlineData("In progress", true)] [InlineData("Blocked", true)] [InlineData("Backlog", false)] [InlineData("Delegated", false)] [InlineData("Review", false)] [InlineData("Done", false)] [InlineData(null, false)] public void IsInProgressOrBlocked_ReturnsCorrectResult(string? state, bool expected) { Assert.Equal(expected, TaskStateHelper.IsInProgressOrBlocked(state)); } // ── TaskStateHelper: IsDoneOrBacklog ── [Theory] [InlineData("Done", true)] [InlineData("Backlog", true)] [InlineData("In progress", false)] [InlineData("Delegated", false)] [InlineData("Review", false)] [InlineData("Blocked", false)] [InlineData(null, false)] public void IsDoneOrBacklog_ReturnsCorrectResult(string? state, bool expected) { Assert.Equal(expected, TaskStateHelper.IsDoneOrBacklog(state)); } // ── TaskStateHelper: ToDisplayString ── [Theory] [InlineData("Backlog", "Offen")] [InlineData("In progress", "In Bearbeitung")] [InlineData("Delegated", "Delegiert")] [InlineData("Review", "Review")] [InlineData("Blocked", "Blockiert")] [InlineData("Done", "Erledigt")] [InlineData("backlog", "Offen")] [InlineData("", "")] [InlineData(null, "")] [InlineData("unknown", "unknown")] public void ToDisplayString_ReturnsGermanLabel(string? state, string expected) { Assert.Equal(expected, TaskStateHelper.ToDisplayString(state)); } // ── TaskState helper: ToStateString and ToTaskState roundtrip ── [Fact] public void ToStateString_And_ToTaskState_RoundTrip() { var states = new[] { TaskState.Backlog, TaskState.InProgress, TaskState.Delegated, TaskState.Review, TaskState.Blocked, TaskState.Done }; foreach (var state in states) { var str = state.ToStateString(); var parsed = str.ToTaskState(); Assert.Equal(state, parsed); } } [Fact] public void ToTaskState_DefaultsToBacklog_ForUnknownString() { Assert.Equal(TaskState.Backlog, "unknown".ToTaskState()); } // ── TaskStateHelper: CanChangeState (Iris + Bao policy) ── [Fact] public void CanChangeState_Iris_CanChangeAnyTask() { var agentTask = new WorkTask { Title = "test", IsAgentTask = true, Source = "iris" }; var normalTask = new WorkTask { Title = "test", IsAgentTask = false, Source = "bao" }; Assert.True(TaskStateHelper.CanChangeState("iris", agentTask)); Assert.True(TaskStateHelper.CanChangeState("iris", normalTask)); } [Fact] public void CanChangeState_Bao_CanChangeAnyTask() { var agentTask = new WorkTask { Title = "test", IsAgentTask = true, Source = "iris" }; var normalTask = new WorkTask { Title = "test", IsAgentTask = false, Source = "bao" }; Assert.True(TaskStateHelper.CanChangeState("bao", agentTask)); Assert.True(TaskStateHelper.CanChangeState("bao", normalTask)); } [Fact] public void CanChangeState_SubAgents_NeverAllowed() { var task = new WorkTask { Title = "test", IsAgentTask = false, Source = "bao" }; Assert.False(TaskStateHelper.CanChangeState("programmer", task)); Assert.False(TaskStateHelper.CanChangeState("reviewer", task)); Assert.False(TaskStateHelper.CanChangeState("architekt", task)); } [Fact] public void CanChangeState_SubAgents_NeverAllowed_EvenForAgentTasks() { var agentTask = new WorkTask { Title = "test", IsAgentTask = true, Source = "iris" }; Assert.False(TaskStateHelper.CanChangeState("programmer", agentTask)); Assert.False(TaskStateHelper.CanChangeState("reviewer", agentTask)); Assert.False(TaskStateHelper.CanChangeState("architekt", agentTask)); } [Fact] public void CanChangeState_NexusSystem_IsAllowed() { var task = new WorkTask { Title = "test", IsAgentTask = false }; Assert.True(TaskStateHelper.CanChangeState("nexus-system", task)); var agentTask = new WorkTask { Title = "test", IsAgentTask = true }; Assert.True(TaskStateHelper.CanChangeState("nexus-system", agentTask)); } [Fact] public void CanChangeState_UnknownCaller_Rejected() { var task = new WorkTask { Title = "test", IsAgentTask = false }; var agentTask = new WorkTask { Title = "test", IsAgentTask = true }; Assert.False(TaskStateHelper.CanChangeState("", task)); Assert.False(TaskStateHelper.CanChangeState("", agentTask)); Assert.False(TaskStateHelper.CanChangeState("unknown", task)); Assert.False(TaskStateHelper.CanChangeState(null, task)); } // ── TaskStateHelper: CanEditContent ── [Fact] public void CanEditContent_Iris_IsAllowed() { Assert.True(TaskStateHelper.CanEditContent("iris")); } [Fact] public void CanEditContent_Bao_IsAllowed() { Assert.True(TaskStateHelper.CanEditContent("bao")); } [Fact] public void CanEditContent_SubAgents_AreAllowed() { Assert.True(TaskStateHelper.CanEditContent("programmer")); Assert.True(TaskStateHelper.CanEditContent("reviewer")); Assert.True(TaskStateHelper.CanEditContent("architekt")); } [Fact] public void CanEditContent_NexusSystem_IsAllowed() { Assert.True(TaskStateHelper.CanEditContent("nexus-system")); } [Fact] public void CanEditContent_UnknownCaller_Rejected() { Assert.False(TaskStateHelper.CanEditContent("")); Assert.False(TaskStateHelper.CanEditContent(null)); Assert.False(TaskStateHelper.CanEditContent(" ")); } }