< Summary

Information
Class: NostrSure.Infrastructure.Client.Implementation.JsonMessageSerializer
Assembly: NostrSure.Infrastructure
File(s): /home/runner/work/NostrSure/NostrSure/NostrSure.Infrastructure/Client/Implementation/JsonMessageSerializer.cs
Line coverage
96%
Covered lines: 51
Uncovered lines: 2
Coverable lines: 53
Total lines: 89
Line coverage: 96.2%
Branch coverage
89%
Covered branches: 34
Total branches: 38
Branch coverage: 89.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Serialize(...)100%44100%
Deserialize(...)90.62%323296.87%
ParseRelayEventMessage(...)50%2287.5%

File(s)

/home/runner/work/NostrSure/NostrSure/NostrSure.Infrastructure/Client/Implementation/JsonMessageSerializer.cs

#LineLine coverage
 1using NostrSure.Domain.Entities;
 2using NostrSure.Infrastructure.Client.Abstractions;
 3using NostrSure.Infrastructure.Client.Messages;
 4using NostrSure.Infrastructure.Serialization;
 5using System.Text.Json;
 6
 7namespace NostrSure.Infrastructure.Client.Implementation;
 8
 9/// <summary>
 10/// JSON serializer for Nostr protocol messages
 11/// </summary>
 12public class JsonMessageSerializer : IMessageSerializer
 13{
 14    private readonly JsonSerializerOptions _options;
 15
 4316    public JsonMessageSerializer()
 4317    {
 4318        _options = new JsonSerializerOptions
 4319        {
 4320            PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
 4321            Converters = { new NostrEventJsonConverter() }
 4322        };
 4323    }
 24
 25    public string Serialize(object[] message)
 1526    {
 1527        if (message == null || message.Length == 0)
 428            throw new ArgumentException("Message cannot be null or empty", nameof(message));
 29
 30        // All outbound messages are valid JSON arrays (requirement R2) since we serialize object arrays
 1131        return JsonSerializer.Serialize(message, _options);
 1132    }
 33
 34    public NostrMessage Deserialize(string json)
 1935    {
 1936        if (string.IsNullOrWhiteSpace(json))
 237            throw new ArgumentException("JSON cannot be null or empty", nameof(json));
 38
 39        try
 1740        {
 1741            using var document = JsonDocument.Parse(json);
 1642            var root = document.RootElement;
 43
 1644            if (root.ValueKind != JsonValueKind.Array)
 145                throw new ArgumentException("Nostr messages must be JSON arrays");
 46
 1547            var arrayLength = root.GetArrayLength();
 1548            if (arrayLength == 0)
 149                throw new ArgumentException("Nostr message array cannot be empty");
 50
 1451            var messageType = root[0].GetString();
 1452            if (string.IsNullOrEmpty(messageType))
 053                throw new ArgumentException("Message type cannot be null or empty");
 54
 1455            return messageType switch
 1456            {
 257                "EVENT" when arrayLength == 3 => ParseRelayEventMessage(root),
 658                "EOSE" when arrayLength == 2 => new EoseMessage(root[1].GetString()!),
 659                "NOTICE" when arrayLength == 2 => new NoticeMessage(root[1].GetString()!),
 460                "CLOSED" when arrayLength >= 2 => new ClosedMessage(
 261                    root[1].GetString()!,
 262                    arrayLength > 2 ? root[2].GetString()! : ""),
 863                "OK" when arrayLength >= 3 => new OkMessage(
 464                    root[1].GetString()!,
 465                    root[2].GetBoolean(),
 466                    arrayLength > 3 ? root[3].GetString()! : ""),
 167                _ => throw new ArgumentException($"Unknown or malformed message type: {messageType}")
 1468            };
 69        }
 170        catch (JsonException ex)
 171        {
 172            throw new ArgumentException($"Invalid JSON: {ex.Message}", ex);
 73        }
 1374    }
 75
 76    // Removed IsValidJsonArray method; validation is handled in Serialize.
 77
 78    private RelayEventMessage ParseRelayEventMessage(JsonElement root)
 179    {
 180        var subscriptionId = root[1].GetString()!;
 181        var eventJson = root[2].GetRawText();
 82
 183        var nostrEvent = JsonSerializer.Deserialize<NostrEvent>(eventJson, _options);
 184        if (nostrEvent == null)
 085            throw new ArgumentException("Failed to parse NostrEvent from relay EVENT message");
 86
 187        return new RelayEventMessage(subscriptionId, nostrEvent);
 188    }
 89}