Files
WireMock.Net-wiremock/test/WireMock.Net.Tests/WebSockets/WebSocketAdvancedTests.cs
Stef Heyenrath a3da39a9ec ws1
2026-02-08 10:30:59 +01:00

335 lines
9.3 KiB
C#

// Copyright © WireMock.Net
#if !NET452
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NFluent;
using WireMock.Models;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.WebSockets;
/// <summary>
/// Advanced and edge case tests for WebSocket functionality
/// </summary>
public class WebSocketAdvancedTests
{
private const string ClientIp = "::1";
[Fact]
public void WebSocketMessage_SwitchingBetweenTextAndBinary()
{
// Arrange
var message = new WebSocketMessage();
// Act - Set as text first
message.BodyAsString = "Hello";
Check.That(message.IsText).IsTrue();
Check.That(message.BodyAsString).IsEqualTo("Hello");
Check.That(message.BodyAsBytes).IsNull();
// Act - Switch to binary
message.BodyAsBytes = new byte[] { 1, 2, 3 };
Check.That(message.IsText).IsFalse();
Check.That(message.BodyAsString).IsNull();
Check.That(message.BodyAsBytes).IsEqualTo(new byte[] { 1, 2, 3 });
}
[Fact]
public void WebSocketMessage_GeneratesUniqueIds()
{
// Arrange & Act
var msg1 = new WebSocketMessage { BodyAsString = "msg1" };
var msg2 = new WebSocketMessage { BodyAsString = "msg2" };
// Assert
Check.That(msg1.Id).IsNotEqualTo(msg2.Id);
Check.That(Guid.Parse(msg1.Id)).IsNotEqualTo(Guid.Empty);
Check.That(Guid.Parse(msg2.Id)).IsNotEqualTo(Guid.Empty);
}
[Fact]
public void WebSocketResponse_EmptyMessages()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act
var response = builder.Build();
// Assert
Check.That(response.Messages).IsEmpty();
Check.That(response.UseTransformer).IsFalse();
Check.That(response.CloseCode).IsNull();
}
[Fact]
public void WebSocketResponse_LargeNumberOfMessages()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act
for (int i = 0; i < 100; i++)
{
builder.WithMessage($"Message {i}", delayMs: i * 10);
}
var response = builder.Build();
// Assert
Check.That(response.Messages).HasSize(100);
Check.That(response.Messages[0].DelayMs).IsEqualTo(0);
Check.That(response.Messages[50].DelayMs).IsEqualTo(500);
Check.That(response.Messages[99].DelayMs).IsEqualTo(990);
}
[Fact]
public void WebSocketResponse_LargeMessage()
{
// Arrange
var largeMessage = new string('x', 1024 * 1024); // 1MB message
var builder = new WebSocketResponseBuilder();
// Act
builder.WithMessage(largeMessage);
var response = builder.Build();
// Assert
Check.That(response.Messages).HasSize(1);
Check.That(response.Messages[0].BodyAsString!.Length).IsEqualTo(1024 * 1024);
}
[Fact]
public void WebSocketResponse_LargeBinaryMessage()
{
// Arrange
var largeData = new byte[1024 * 1024]; // 1MB binary data
for (int i = 0; i < largeData.Length; i++)
{
largeData[i] = (byte)(i % 256);
}
var builder = new WebSocketResponseBuilder();
// Act
builder.WithBinaryMessage(largeData);
var response = builder.Build();
// Assert
Check.That(response.Messages).HasSize(1);
Check.That(response.Messages[0].BodyAsBytes!.Length).IsEqualTo(1024 * 1024);
}
[Fact]
public void WebSocketResponse_SpecialCharactersInMessages()
{
// Arrange
var specialMessages = new[]
{
"Message with \"quotes\"",
"Message with 'apostrophes'",
"Message with\nnewlines",
"Message with\ttabs",
"Unicode: 你好世界 🌍",
"Emoji: 😀 😃 😄"
};
var builder = new WebSocketResponseBuilder();
// Act
foreach (var msg in specialMessages)
{
builder.WithMessage(msg);
}
var response = builder.Build();
// Assert
Check.That(response.Messages).HasSize(specialMessages.Length);
for (int i = 0; i < specialMessages.Length; i++)
{
Check.That(response.Messages[i].BodyAsString).IsEqualTo(specialMessages[i]);
}
}
[Fact]
public void WebSocketResponse_JsonWithComplexObjects()
{
// Arrange
var complexObject = new
{
id = 123,
name = "Test",
nested = new
{
array = new[] { 1, 2, 3 },
innerObj = new { prop = "value" }
},
timestamp = DateTime.UtcNow
};
var builder = new WebSocketResponseBuilder();
// Act
builder.WithJsonMessage(complexObject);
var response = builder.Build();
// Assert
Check.That(response.Messages).HasSize(1);
Check.That(response.Messages[0].BodyAsString).Contains("\"id\"");
Check.That(response.Messages[0].BodyAsString).Contains("\"nested\"");
Check.That(response.Messages[0].BodyAsString).Contains("\"array\"");
}
[Fact]
public void WebSocketResponse_NullJsonObject()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act & Assert
Check.ThatCode(() => builder.WithJsonMessage(null!)).Throws<ArgumentException>();
}
[Fact]
public void WebSocketResponse_CloseWithoutMessage()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act
builder.WithClose(1000); // No message
var response = builder.Build();
// Assert
Check.That(response.CloseCode).IsEqualTo(1000);
Check.That(response.CloseMessage).IsNull();
}
[Fact]
public void WebSocketResponse_CloseWithMessage()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act
builder.WithClose(1001, "Going away");
var response = builder.Build();
// Assert
Check.That(response.CloseCode).IsEqualTo(1001);
Check.That(response.CloseMessage).IsEqualTo("Going away");
}
[Fact]
public void WebSocketResponse_VariousCloseCodes()
{
// Arrange
var closeCodes = new[] { 1000, 1001, 1002, 1003, 1008, 1011, 4000 };
// Act & Assert
foreach (var code in closeCodes)
{
var builder = new WebSocketResponseBuilder();
builder.WithClose(code);
var response = builder.Build();
Check.That(response.CloseCode).IsEqualTo(code);
}
}
[Fact]
public void WebSocketResponse_ReusableBuilder()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act - First build
builder.WithMessage("Message 1");
var response1 = builder.Build();
// Add more messages and build again
builder.WithMessage("Message 2");
var response2 = builder.Build();
// Assert - response2 includes all messages
Check.That(response1.Messages).HasSize(1);
Check.That(response2.Messages).HasSize(2); // Both from builder
}
[Fact]
public void WebSocketResponse_DelayProgressions()
{
// Arrange - Test various delay patterns
var builder = new WebSocketResponseBuilder();
// Act - Linear progression
builder.WithMessage("0ms", delayMs: 0);
builder.WithMessage("100ms", delayMs: 100);
builder.WithMessage("200ms", delayMs: 200);
builder.WithMessage("300ms", delayMs: 300);
var response = builder.Build();
// Assert
for (int i = 0; i < response.Messages.Count; i++)
{
Check.That(response.Messages[i].DelayMs).IsEqualTo(i * 100);
}
}
[Fact]
public void WebSocketResponse_TransformerToggle()
{
// Arrange
var builder = new WebSocketResponseBuilder();
// Act - Enable transformer
builder.WithMessage("Template {{variable}}");
builder.WithTransformer(TransformerType.Handlebars);
var responseWithTransformer = builder.Build();
// Assert
Check.That(responseWithTransformer.UseTransformer).IsTrue();
Check.That(responseWithTransformer.TransformerType).IsEqualTo(TransformerType.Handlebars);
}
[Fact]
public void WebSocketResponse_Subprotocol_Variations()
{
// Arrange
var subprotocols = new[] { "v1", "chat-v1", "my-protocol", "x-custom" };
// Act & Assert
foreach (var subprotocol in subprotocols)
{
var builder = new WebSocketResponseBuilder();
builder.WithSubprotocol(subprotocol);
var response = builder.Build();
Check.That(response.Subprotocol).IsEqualTo(subprotocol);
}
}
[Fact]
public void WebSocketResponse_AutoClose_Variations()
{
// Arrange
var delays = new[] { 0, 100, 500, 1000, 5000 };
// Act & Assert
foreach (var delay in delays)
{
var builder = new WebSocketResponseBuilder();
builder.WithAutoClose(delayMs: delay);
var response = builder.Build();
Check.That(response.AutoCloseDelayMs).IsEqualTo(delay);
}
}
}
#endif