IdentityShroud/IdentityShroud.Api.Tests/Apis/ClientApiTests.cs
2026-02-22 09:27:57 +01:00

179 lines
5.7 KiB
C#

using System.Net;
using System.Net.Http.Json;
using IdentityShroud.Core;
using IdentityShroud.Core.Model;
using IdentityShroud.Core.Tests.Fixtures;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace IdentityShroud.Api.Tests.Apis;
public class ClientApiTests : IClassFixture<ApplicationFactory>
{
private readonly ApplicationFactory _factory;
public ClientApiTests(ApplicationFactory factory)
{
_factory = factory;
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<Db>();
if (!db.Database.EnsureCreated())
{
db.Database.ExecuteSqlRaw("TRUNCATE realm CASCADE;");
}
}
[Theory]
[InlineData(null, false, "ClientId")]
[InlineData("", false, "ClientId")]
[InlineData("my-client", true, "")]
public async Task Create_Validation(string? clientId, bool succeeds, string fieldName)
{
// setup
Realm realm = await CreateRealmAsync("test-realm", "Test Realm");
var client = _factory.CreateClient();
// act
var response = await client.PostAsync(
$"/api/v1/realms/{realm.Id}/clients",
JsonContent.Create(new { ClientId = clientId }),
TestContext.Current.CancellationToken);
#if DEBUG
string contents = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
#endif
if (succeeds)
{
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
}
else
{
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var problemDetails =
await response.Content.ReadFromJsonAsync<ValidationProblemDetails>(
TestContext.Current.CancellationToken);
Assert.Contains(problemDetails!.Errors, e => e.Key == fieldName);
}
}
[Fact]
public async Task Create_Success_ReturnsCreatedWithLocation()
{
// setup
Realm realm = await CreateRealmAsync("create-realm", "Create Realm");
var client = _factory.CreateClient();
// act
var response = await client.PostAsync(
$"/api/v1/realms/{realm.Id}/clients",
JsonContent.Create(new { ClientId = "new-client", Name = "New Client" }),
TestContext.Current.CancellationToken);
#if DEBUG
string contents = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
#endif
// verify
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
var body = await response.Content.ReadFromJsonAsync<ClientCreateReponse>(
TestContext.Current.CancellationToken);
Assert.NotNull(body);
Assert.Equal("new-client", body.ClientId);
Assert.True(body.Id > 0);
}
[Fact]
public async Task Create_UnknownRealm_ReturnsNotFound()
{
var client = _factory.CreateClient();
var response = await client.PostAsync(
$"/api/v1/realms/{Guid.NewGuid()}/clients",
JsonContent.Create(new { ClientId = "some-client" }),
TestContext.Current.CancellationToken);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact]
public async Task Get_Success()
{
// setup
Realm realm = await CreateRealmAsync("get-realm", "Get Realm");
Client dbClient = await CreateClientAsync(realm, "get-client", "Get Client");
var httpClient = _factory.CreateClient();
// act
var response = await httpClient.GetAsync(
$"/api/v1/realms/{realm.Id}/clients/{dbClient.Id}",
TestContext.Current.CancellationToken);
#if DEBUG
string contents = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
#endif
// verify
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadFromJsonAsync<ClientRepresentation>(
TestContext.Current.CancellationToken);
Assert.NotNull(body);
Assert.Equal(dbClient.Id, body.Id);
Assert.Equal("get-client", body.ClientId);
Assert.Equal("Get Client", body.Name);
Assert.Equal(realm.Id, body.RealmId);
}
[Fact]
public async Task Get_UnknownClient_ReturnsNotFound()
{
// setup
Realm realm = await CreateRealmAsync("notfound-realm", "NotFound Realm");
var httpClient = _factory.CreateClient();
// act
var response = await httpClient.GetAsync(
$"/api/v1/realms/{realm.Id}/clients/99999",
TestContext.Current.CancellationToken);
// verify
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
private async Task<Realm> CreateRealmAsync(string slug, string name)
{
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<Db>();
var realm = new Realm { Slug = slug, Name = name };
db.Realms.Add(realm);
await db.SaveChangesAsync(TestContext.Current.CancellationToken);
return realm;
}
private async Task<Client> CreateClientAsync(Realm realm, string clientId, string? name = null)
{
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<Db>();
var client = new Client
{
RealmId = realm.Id,
ClientId = clientId,
Name = name,
CreatedAt = DateTime.UtcNow,
};
db.Clients.Add(client);
await db.SaveChangesAsync(TestContext.Current.CancellationToken);
return client;
}
}