//
// Copyright (c) StellaOps. Licensed under AGPL-3.0-or-later.
//
using System.Text.Json;
using FluentAssertions;
namespace StellaOps.HybridLogicalClock.Tests;
///
/// Unit tests for .
///
[Trait("Category", "Unit")]
public sealed class HlcTimestampJsonConverterTests
{
private readonly JsonSerializerOptions _options = new()
{
Converters = { new HlcTimestampJsonConverter() }
};
[Fact]
public void Serialize_ProducesSortableString()
{
// Arrange
var timestamp = new HlcTimestamp
{
PhysicalTime = 1704067200000,
NodeId = "node1",
LogicalCounter = 42
};
// Act
var json = JsonSerializer.Serialize(timestamp, _options);
// Assert
json.Should().Be("\"1704067200000-node1-000042\"");
}
[Fact]
public void Deserialize_ParsesSortableString()
{
// Arrange
var json = "\"1704067200000-node1-000042\"";
// Act
var result = JsonSerializer.Deserialize(json, _options);
// Assert
result.PhysicalTime.Should().Be(1704067200000);
result.NodeId.Should().Be("node1");
result.LogicalCounter.Should().Be(42);
}
[Fact]
public void RoundTrip_PreservesValues()
{
// Arrange
var original = new HlcTimestamp
{
PhysicalTime = 1704067200000,
NodeId = "scheduler-east-1",
LogicalCounter = 999
};
// Act
var json = JsonSerializer.Serialize(original, _options);
var deserialized = JsonSerializer.Deserialize(json, _options);
// Assert
deserialized.Should().Be(original);
}
[Fact]
public void Deserialize_Null_ReturnsZero()
{
// Arrange
var json = "null";
// Act
var result = JsonSerializer.Deserialize(json, _options);
// Assert
result.Should().Be(default(HlcTimestamp));
}
[Fact]
public void Deserialize_InvalidFormat_ThrowsJsonException()
{
// Arrange
var json = "\"invalid\"";
// Act
var act = () => JsonSerializer.Deserialize(json, _options);
// Assert
act.Should().Throw();
}
[Fact]
public void Deserialize_WrongTokenType_ThrowsJsonException()
{
// Arrange
var json = "12345"; // number, not string
// Act
var act = () => JsonSerializer.Deserialize(json, _options);
// Assert
act.Should().Throw();
}
[Fact]
public void SerializeInObject_WorksCorrectly()
{
// Arrange
var obj = new TestWrapper
{
Timestamp = new HlcTimestamp
{
PhysicalTime = 1704067200000,
NodeId = "node1",
LogicalCounter = 1
},
Name = "Test"
};
// Act
var json = JsonSerializer.Serialize(obj, _options);
var deserialized = JsonSerializer.Deserialize(json, _options);
// Assert
deserialized.Should().NotBeNull();
deserialized!.Timestamp.Should().Be(obj.Timestamp);
deserialized.Name.Should().Be(obj.Name);
}
private sealed class TestWrapper
{
public HlcTimestamp Timestamp { get; set; }
public string? Name { get; set; }
}
}