91 lines
3.6 KiB
C#
91 lines
3.6 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using StellaOps.TestKit;
|
|
|
|
namespace StellaOps.Scanner.WebService.Tests;
|
|
|
|
public sealed class RegistryEndpointsTests
|
|
{
|
|
[Trait("Category", TestCategories.Unit)]
|
|
[Fact]
|
|
public async Task RegistrySearchAndDigestEndpoints_ReturnExpectedResults()
|
|
{
|
|
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
|
await factory.InitializeAsync();
|
|
using var client = factory.CreateClient();
|
|
|
|
var searchResponse = await client.GetAsync(
|
|
"/api/v1/registries/images/search?q=nginx",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.Equal(HttpStatusCode.OK, searchResponse.StatusCode);
|
|
|
|
var searchPayload = await searchResponse.Content.ReadFromJsonAsync<RegistrySearchResponse>(
|
|
cancellationToken: TestContext.Current.CancellationToken);
|
|
Assert.NotNull(searchPayload);
|
|
Assert.Contains(searchPayload!.Items, item => item.Repository == "library/nginx");
|
|
|
|
var digestResponse = await client.GetAsync(
|
|
"/api/v1/registries/images/digests?repository=library/nginx",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.Equal(HttpStatusCode.OK, digestResponse.StatusCode);
|
|
|
|
var digestPayload = await digestResponse.Content.ReadFromJsonAsync<RegistryDigestResponse>(
|
|
cancellationToken: TestContext.Current.CancellationToken);
|
|
Assert.NotNull(digestPayload);
|
|
Assert.Equal("library/nginx", digestPayload!.Repository);
|
|
Assert.NotEmpty(digestPayload.Digests);
|
|
Assert.All(digestPayload.Digests, item => Assert.StartsWith("sha256:", item.Digest, StringComparison.Ordinal));
|
|
}
|
|
|
|
[Trait("Category", TestCategories.Unit)]
|
|
[Fact]
|
|
public async Task UnknownRepositoryDigest_IsDeterministicAcrossRequests()
|
|
{
|
|
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
|
await factory.InitializeAsync();
|
|
using var client = factory.CreateClient();
|
|
|
|
var first = await client.GetFromJsonAsync<RegistryDigestResponse>(
|
|
"/api/v1/registries/images/digests?repository=example/custom-service",
|
|
TestContext.Current.CancellationToken);
|
|
var second = await client.GetFromJsonAsync<RegistryDigestResponse>(
|
|
"/api/v1/registries/images/digests?repository=example/custom-service",
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.NotNull(first);
|
|
Assert.NotNull(second);
|
|
Assert.Equal(first!.Digests[0].Digest, second!.Digests[0].Digest);
|
|
}
|
|
|
|
public sealed class RegistrySearchResponse
|
|
{
|
|
public RegistryImageDto[] Items { get; set; } = [];
|
|
public int TotalCount { get; set; }
|
|
public string? RegistryId { get; set; }
|
|
}
|
|
|
|
public sealed class RegistryDigestResponse
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string Repository { get; set; } = string.Empty;
|
|
public string[] Tags { get; set; } = [];
|
|
public RegistryDigestEntry[] Digests { get; set; } = [];
|
|
}
|
|
|
|
public sealed class RegistryImageDto
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string Repository { get; set; } = string.Empty;
|
|
public string[] Tags { get; set; } = [];
|
|
public RegistryDigestEntry[] Digests { get; set; } = [];
|
|
public string LastPushed { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class RegistryDigestEntry
|
|
{
|
|
public string Tag { get; set; } = string.Empty;
|
|
public string Digest { get; set; } = string.Empty;
|
|
public string PushedAt { get; set; } = string.Empty;
|
|
}
|
|
}
|