Refine ship orders and viewer controls
This commit is contained in:
140
tests/backend/ShipOrderQueueTests.cs
Normal file
140
tests/backend/ShipOrderQueueTests.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using FluentAssertions;
|
||||
using SpaceGame.Api.Shared.Runtime;
|
||||
using SpaceGame.Api.Ships.Runtime;
|
||||
using Xunit;
|
||||
|
||||
namespace SpaceGame.Api.Tests;
|
||||
|
||||
public sealed class ShipOrderQueueTests
|
||||
{
|
||||
[Fact]
|
||||
public void Enqueue_Throws_WhenQueueIsFull()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
foreach (var index in Enumerable.Range(0, ShipOrderQueue.MaxOrders))
|
||||
{
|
||||
queue.Enqueue(CreateOrder($"order-{index}", ShipOrderSourceKind.Player, priority: index));
|
||||
}
|
||||
|
||||
var act = () => queue.Enqueue(CreateOrder("overflow", ShipOrderSourceKind.Player));
|
||||
|
||||
act.Should().Throw<InvalidOperationException>()
|
||||
.WithMessage("Order queue is full.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCurrentOrder_UsesQueueOrder()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueuePlayerOrder(CreateOrder("player-first", ShipOrderSourceKind.Player));
|
||||
queue.EnqueueManagedOrder(CreateOrder("commander-second", ShipOrderSourceKind.Commander, priority: 100));
|
||||
queue.EnqueueManagedOrder(CreateOrder("behavior-third", ShipOrderSourceKind.Behavior, priority: 999));
|
||||
|
||||
var currentOrder = queue.GetCurrentOrder();
|
||||
|
||||
currentOrder.Should().NotBeNull();
|
||||
currentOrder!.Id.Should().Be("player-first");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCurrentOrder_IgnoresTerminalStatuses()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueuePlayerOrder(CreateOrder("completed-player", ShipOrderSourceKind.Player, priority: 100, status: OrderStatus.Completed));
|
||||
queue.EnqueueManagedOrder(CreateOrder("active-commander", ShipOrderSourceKind.Commander, priority: 1, status: OrderStatus.Active));
|
||||
|
||||
var currentOrder = queue.GetCurrentOrder();
|
||||
|
||||
currentOrder.Should().NotBeNull();
|
||||
currentOrder!.Id.Should().Be("active-commander");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnqueuePlayerOrder_InsertsBeforeManagedOrders()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueueManagedOrder(CreateOrder("behavior-1", ShipOrderSourceKind.Behavior));
|
||||
queue.EnqueuePlayerOrder(CreateOrder("player-1", ShipOrderSourceKind.Player));
|
||||
queue.EnqueueManagedOrder(CreateOrder("behavior-2", ShipOrderSourceKind.Commander));
|
||||
queue.EnqueuePlayerOrder(CreateOrder("player-2", ShipOrderSourceKind.Player));
|
||||
|
||||
queue.Select(order => order.Id).Should().Equal("player-1", "player-2", "behavior-1", "behavior-2");
|
||||
queue.FindLeadingOrderForSource(ShipOrderSourceKind.Player)!.Id.Should().Be("player-1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddOrReplaceManagedOrder_ReplacesMatchingOrderWithoutGrowingQueue()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueueManagedOrder(CreateOrder("order-1", ShipOrderSourceKind.Behavior, label: "Initial label"));
|
||||
|
||||
queue.AddOrReplaceManagedOrder(CreateOrder("order-1", ShipOrderSourceKind.Behavior, label: "Updated label", priority: 7));
|
||||
|
||||
queue.Count.Should().Be(1);
|
||||
queue.FindById("order-1").Should().NotBeNull();
|
||||
queue.FindById("order-1")!.Label.Should().Be("Updated label");
|
||||
queue.FindById("order-1")!.Priority.Should().Be(7);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveById_RemovesMatchingOrder()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueuePlayerOrder(CreateOrder("remove-me", ShipOrderSourceKind.Player));
|
||||
queue.EnqueuePlayerOrder(CreateOrder("keep-me", ShipOrderSourceKind.Player));
|
||||
|
||||
var removed = queue.RemoveById("remove-me");
|
||||
|
||||
removed.Should().BeTrue();
|
||||
queue.Select(order => order.Id).Should().ContainSingle().Which.Should().Be("keep-me");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryMovePlayerOrder_ReordersWithinPlayerSegment()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueuePlayerOrder(CreateOrder("player-1", ShipOrderSourceKind.Player));
|
||||
queue.EnqueuePlayerOrder(CreateOrder("player-2", ShipOrderSourceKind.Player));
|
||||
queue.EnqueueManagedOrder(CreateOrder("behavior-1", ShipOrderSourceKind.Behavior));
|
||||
|
||||
var moved = queue.TryMovePlayerOrder("player-2", 0);
|
||||
|
||||
moved.Should().BeTrue();
|
||||
queue.Select(order => order.Id).Should().Equal("player-2", "player-1", "behavior-1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryCompleteOrder_RemovesCompletedDirectOrderFromQueue()
|
||||
{
|
||||
var queue = new ShipOrderQueue();
|
||||
queue.EnqueuePlayerOrder(CreateOrder("direct-order", ShipOrderSourceKind.Player, status: OrderStatus.Active));
|
||||
queue.EnqueueManagedOrder(CreateOrder("behavior-order", ShipOrderSourceKind.Behavior));
|
||||
|
||||
var completed = queue.TryCompleteOrder("direct-order");
|
||||
|
||||
completed.Should().BeTrue();
|
||||
queue.FindById("direct-order").Should().BeNull();
|
||||
queue.GetCurrentOrder()!.Id.Should().Be("behavior-order");
|
||||
}
|
||||
|
||||
private static ShipOrderRuntime CreateOrder(
|
||||
string id,
|
||||
ShipOrderSourceKind sourceKind,
|
||||
int priority = 0,
|
||||
OrderStatus status = OrderStatus.Queued,
|
||||
string? label = null,
|
||||
DateTimeOffset? createdAtUtc = null)
|
||||
{
|
||||
return new ShipOrderRuntime
|
||||
{
|
||||
Id = id,
|
||||
Kind = "test-order",
|
||||
SourceKind = sourceKind,
|
||||
SourceId = $"{sourceKind}-source",
|
||||
Priority = priority,
|
||||
Status = status,
|
||||
Label = label,
|
||||
CreatedAtUtc = createdAtUtc ?? new DateTimeOffset(2026, 4, 8, 12, 0, 0, TimeSpan.Zero),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user