mishima-nexus-client-csharp/tests/Robotico.Nexus.Client.Tests/Graph/NexusGraphSessionTests.cs

251 lines
8.0 KiB
C#
Raw Permalink Normal View History

using Robotico.Graph;
using Robotico.Nexus.Client.Tests.TestSupport;
using Robotico.Result.Errors;
using Xunit;
namespace Robotico.Nexus.Client.Tests.Graph;
public class NexusGraphSessionTests : IAsyncLifetime
{
private NexusTestHost _host = null!;
private NexusClient _client = null!;
private IGraphSession _session = null!;
public async Task InitializeAsync()
{
_host = await NexusTestHost.StartAsync();
Robotico.Result.Result<NexusClient> connected = NexusClient.Connect(_host.ConnectionUri(NexusUriSchemes.Graph));
Assert.True(connected.IsSuccess(out NexusClient? client, out _));
_client = client!;
Robotico.Result.Result<IGraphSession> opened = _client.Graph.Open("session-db");
Assert.True(opened.IsSuccess(out IGraphSession? session, out _));
_session = session!;
}
public async Task DisposeAsync()
{
_session.Dispose();
_client.Dispose();
await _host.DisposeAsync();
}
[Fact]
public void RegisterLabel_Succeeds()
{
Robotico.Result.Result result = _session.RegisterLabel("Person");
Assert.True(result.IsSuccess());
}
[Fact]
public void RegisterLabel_Fails_WhenBlank()
{
Robotico.Result.Result result = _session.RegisterLabel(" ");
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void RegisterEdgeType_Succeeds()
{
Robotico.Result.Result result = _session.RegisterEdgeType("WorksAt");
Assert.True(result.IsSuccess());
}
[Fact]
public void RegisterEdgeType_Fails_WhenBlank()
{
Robotico.Result.Result result = _session.RegisterEdgeType(string.Empty);
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void UpsertVertex_ThenGetVertex_RoundTrips()
{
Robotico.Result.Result<ulong> upserted = _session.UpsertVertex(1, ["Person"]);
Assert.True(upserted.IsSuccess());
Robotico.Result.Result<GraphVertex> fetched = _session.GetVertex(1);
Assert.True(fetched.IsSuccess(out GraphVertex? vertex, out _));
Assert.Equal(1ul, vertex!.VertexId);
Assert.Contains("Person", vertex.Labels);
}
[Fact]
public void UpsertVertex_Fails_WhenNoLabels()
{
Robotico.Result.Result<ulong> result = _session.UpsertVertex(1, []);
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void GetVertex_Fails_WhenNotFound()
{
Robotico.Result.Result<GraphVertex> result = _session.GetVertex(999);
Assert.True(result.IsError(out IError? error));
Assert.Equal(NexusErrors.NotFound, error!.Code);
}
[Fact]
public void DeleteVertex_Succeeds()
{
_session.UpsertVertex(2, ["Person"]);
Robotico.Result.Result<ulong> result = _session.DeleteVertex(2);
Assert.True(result.IsSuccess());
Assert.True(_session.GetVertex(2).IsError(out _));
}
[Fact]
public void UpsertEdge_ThenGetEdge_RoundTrips()
{
_session.UpsertVertex(1, ["Person"]);
_session.UpsertVertex(2, ["Company"]);
Robotico.Result.Result<ulong> upserted = _session.UpsertEdge(1, 2, "WorksAt");
Assert.True(upserted.IsSuccess());
Robotico.Result.Result<GraphEdge> fetched = _session.GetEdge(1, 2, "WorksAt");
Assert.True(fetched.IsSuccess(out GraphEdge? edge, out _));
Assert.Equal(1ul, edge!.SourceVertexId);
Assert.Equal(2ul, edge.TargetVertexId);
Assert.Equal("WorksAt", edge.EdgeTypeName);
}
[Fact]
public void UpsertEdge_Fails_WhenEdgeTypeBlank()
{
Robotico.Result.Result<ulong> result = _session.UpsertEdge(1, 2, string.Empty);
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void DeleteEdge_Succeeds()
{
_session.UpsertVertex(1, ["Person"]);
_session.UpsertVertex(2, ["Company"]);
_session.UpsertEdge(1, 2, "WorksAt");
Robotico.Result.Result<ulong> result = _session.DeleteEdge(1, 2, "WorksAt");
Assert.True(result.IsSuccess());
Assert.True(_session.GetEdge(1, 2, "WorksAt").IsError(out _));
}
[Fact]
public void DeleteEdge_Fails_WhenEdgeTypeBlank()
{
Robotico.Result.Result<ulong> result = _session.DeleteEdge(1, 2, " ");
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void GetEdge_Fails_WhenEdgeTypeBlank()
{
Robotico.Result.Result<GraphEdge> result = _session.GetEdge(1, 2, string.Empty);
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void GetEdge_Fails_WhenNotFound()
{
Robotico.Result.Result<GraphEdge> result = _session.GetEdge(1, 2, "Missing");
Assert.True(result.IsError(out IError? error));
Assert.Equal(NexusErrors.NotFound, error!.Code);
}
[Fact]
public void GetNeighborhood_ReturnsStartVertex()
{
Robotico.Result.Result<GraphNeighborhood> result = _session.GetNeighborhood(1, maxDepth: 2, edgeTypeName: "WorksAt");
Assert.True(result.IsSuccess(out GraphNeighborhood? neighborhood, out _));
Assert.Equal(1ul, neighborhood!.StartVertexId);
Assert.Contains(1ul, neighborhood.VisitOrder);
}
[Fact]
public void GetNeighborhood_Succeeds_WithoutOptionalArguments()
{
Robotico.Result.Result<GraphNeighborhood> result = _session.GetNeighborhood(1);
Assert.True(result.IsSuccess());
}
[Fact]
public void ListVerticesByLabel_ReturnsMatchingVertices()
{
_session.UpsertVertex(10, ["Person"]);
_session.UpsertVertex(11, ["Person"]);
_session.UpsertVertex(12, ["Company"]);
Robotico.Result.Result<GraphVertexPage> result = _session.ListVerticesByLabel("Person", skip: 0, limit: 25);
Assert.True(result.IsSuccess(out GraphVertexPage? page, out _));
Assert.Equal("Person", page!.LabelName);
Assert.Equal(2, page.TotalCount);
}
[Fact]
public void ListVerticesByLabel_Fails_WhenLabelBlank()
{
Robotico.Result.Result<GraphVertexPage> result = _session.ListVerticesByLabel(string.Empty);
Assert.True(result.IsError(out IError? error));
Assert.Equal(GraphErrors.InvalidArgument, error!.Code);
}
[Fact]
public void AllOperations_Fail_AfterDispose()
{
_session.Dispose();
Assert.True(_session.RegisterLabel("x").IsError(out IError? e1));
Assert.Equal(NexusErrors.Disposed, e1!.Code);
Assert.True(_session.RegisterEdgeType("x").IsError(out IError? e2));
Assert.Equal(NexusErrors.Disposed, e2!.Code);
Assert.True(_session.UpsertVertex(1, ["A"]).IsError(out IError? e3));
Assert.Equal(NexusErrors.Disposed, e3!.Code);
Assert.True(_session.DeleteVertex(1).IsError(out IError? e4));
Assert.Equal(NexusErrors.Disposed, e4!.Code);
Assert.True(_session.GetVertex(1).IsError(out IError? e5));
Assert.Equal(NexusErrors.Disposed, e5!.Code);
Assert.True(_session.UpsertEdge(1, 2, "x").IsError(out IError? e6));
Assert.Equal(NexusErrors.Disposed, e6!.Code);
Assert.True(_session.DeleteEdge(1, 2, "x").IsError(out IError? e7));
Assert.Equal(NexusErrors.Disposed, e7!.Code);
Assert.True(_session.GetEdge(1, 2, "x").IsError(out IError? e8));
Assert.Equal(NexusErrors.Disposed, e8!.Code);
Assert.True(_session.GetNeighborhood(1).IsError(out IError? e9));
Assert.Equal(NexusErrors.Disposed, e9!.Code);
Assert.True(_session.ListVerticesByLabel("x").IsError(out IError? e10));
Assert.Equal(NexusErrors.Disposed, e10!.Code);
}
}