Files
ReC/tests/ReC.Tests/Client/RecActionApiTests.cs
TekH 340349a2d5 Add tests for GetDynamicAsync method in RecActionApiTests
Added a `using` directive for `System.Text.Json` to support JSON
operations. Introduced two new test methods:
`GetDynamicAsync_without_filters_returns_dynamic_payload_or_throws_not_found`
to validate the behavior of `GetDynamicAsync` without filters, and
`GetDynamicAsync_with_unknown_profile_throws_not_found` to ensure
proper handling of unknown profile IDs.
2026-05-20 11:41:43 +02:00

197 lines
6.4 KiB
C#

using System.Net;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using ReC.Application.Common.Dto;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
using ReC.Application.RecActions.Commands;
using ReC.Client;
using ReC.Client.Api;
using ClientInvokeReferences = ReC.Client.Api.InvokeReferences;
namespace ReC.Tests.Client;
[TestFixture]
public class RecActionApiTests : RecClientTestBase
{
[Test]
public void ReCClient_is_resolvable_through_dependency_injection()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
Assert.That(client, Is.Not.Null);
Assert.That(client.RecActions, Is.Not.Null);
}
[Test]
public async Task GetAsync_without_filters_returns_deserialized_result_or_throws_not_found()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
try
{
var actions = await client.RecActions.GetAsync<RecActionViewDto[]>();
Assert.That(actions, Is.Not.Null);
}
catch (ReCApiException ex)
{
Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
Assert.That(ex.Method, Is.EqualTo("GET"));
Assert.That(ex.RequestUri!.AbsolutePath, Does.EndWith("api/RecAction"));
}
}
[Test]
public async Task GetDynamicAsync_without_filters_returns_dynamic_payload_or_throws_not_found()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
try
{
dynamic? actions = await client.RecActions.GetDynamicAsync();
Assert.That(actions, Is.Not.Null);
Assert.That(actions, Is.TypeOf<JsonElement>());
Assert.That(((JsonElement)actions).ValueKind, Is.EqualTo(JsonValueKind.Array));
}
catch (ReCApiException ex)
{
Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
Assert.That(ex.Method, Is.EqualTo("GET"));
Assert.That(ex.RequestUri!.AbsolutePath, Does.EndWith("api/RecAction"));
}
}
[Test]
public async Task GetAsync_with_profile_filter_returns_only_matching_actions()
{
var profileId = Configuration.GetValue<long?>("FakeProfileId");
if (profileId is null or <= 0)
Assert.Ignore("FakeProfileId must be configured in appsettings.json for this test.");
var (client, scope) = CreateScopedClient();
using var _ = scope;
RecActionViewDto[]? actions;
try
{
actions = await client.RecActions.GetAsync<RecActionViewDto[]>(profileId: profileId);
}
catch (ReCApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
Assert.Pass("NotFound is acceptable when test data is unavailable.");
return;
}
Assert.That(actions, Is.Not.Null.And.Not.Empty);
Assert.That(actions, Has.All.Matches<RecActionViewDto>(a => a.ProfileId == profileId));
}
[Test]
public void GetAsync_with_unknown_profile_throws_not_found()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var ex = Assert.ThrowsAsync<ReCApiException>(async () =>
await client.RecActions.GetAsync<RecActionViewDto[]>(profileId: long.MaxValue));
Assert.That(ex, Is.Not.Null);
Assert.That(ex!.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
Assert.That(ex.Method, Is.EqualTo("GET"));
Assert.That(ex.RequestUri!.Query, Does.Contain("ProfileId="));
}
[Test]
public void GetDynamicAsync_with_unknown_profile_throws_not_found()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var ex = Assert.ThrowsAsync<ReCApiException>(async () =>
await client.RecActions.GetDynamicAsync(profileId: long.MaxValue));
Assert.That(ex, Is.Not.Null);
Assert.That(ex!.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
Assert.That(ex.Method, Is.EqualTo("GET"));
Assert.That(ex.RequestUri!.Query, Does.Contain("ProfileId="));
}
[Test]
public void CreateAsync_with_invalid_foreign_key_throws_ReCApiException()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var payload = new InsertActionCommand
{
ProfileId = long.MaxValue,
EndpointId = long.MaxValue,
Active = true,
Sequence = 1
};
var ex = Assert.ThrowsAsync<ReCApiException>(async () => await client.RecActions.CreateAsync(payload));
Assert.That(ex, Is.Not.Null);
Assert.That((int)ex!.StatusCode, Is.GreaterThanOrEqualTo(400));
Assert.That(ex.Method, Is.EqualTo("POST"));
}
[Test]
public void UpdateAsync_with_unknown_id_throws_ReCApiException_with_method_PUT()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var unknownId = long.MaxValue;
var payload = new UpdateActionDto
{
ProfileId = 1,
Active = false,
Sequence = 1
};
var ex = Assert.ThrowsAsync<ReCApiException>(async () => await client.RecActions.UpdateAsync(unknownId, payload));
Assert.That(ex, Is.Not.Null);
Assert.That(ex!.Method, Is.EqualTo("PUT"));
}
[Test]
public void DeleteAsync_sends_payload_as_query_string_not_body()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var payload = new DeleteActionCommand
{
Start = long.MaxValue - 1,
End = long.MaxValue,
Force = false
};
try
{
client.RecActions.DeleteAsync(payload).GetAwaiter().GetResult();
}
catch (ReCApiException ex)
{
Assert.That(ex.Method, Is.EqualTo("DELETE"));
Assert.That(ex.RequestUri!.Query, Does.Contain("Start=").And.Contains("End=").And.Contains("Force="));
}
}
[Test]
public void InvokeAsync_with_unknown_profile_throws_ReCApiException()
{
var (client, scope) = CreateScopedClient();
using var _ = scope;
var ex = Assert.ThrowsAsync<ReCApiException>(async () =>
await client.RecActions.InvokeAsync(long.MaxValue, new ClientInvokeReferences { BatchId = "test-batch" }));
Assert.That(ex, Is.Not.Null);
Assert.That(ex!.Method, Is.EqualTo("POST"));
}
}