Add unit tests and implementations for MongoDB index models and OpenAPI metadata
- Implemented `MongoIndexModelTests` to verify index models for various stores. - Created `OpenApiMetadataFactory` with methods to generate OpenAPI metadata. - Added tests for `OpenApiMetadataFactory` to ensure expected defaults and URL overrides. - Introduced `ObserverSurfaceSecrets` and `WebhookSurfaceSecrets` for managing secrets. - Developed `RuntimeSurfaceFsClient` and `WebhookSurfaceFsClient` for manifest retrieval. - Added dependency injection tests for `SurfaceEnvironmentRegistration` in both Observer and Webhook contexts. - Implemented tests for secret resolution in `ObserverSurfaceSecretsTests` and `WebhookSurfaceSecretsTests`. - Created `EnsureLinkNotMergeCollectionsMigrationTests` to validate MongoDB migration logic. - Added project files for MongoDB tests and NuGet package mirroring.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace StellaOps.Notify.Storage.Mongo.Documents;
|
||||
|
||||
public sealed class PackApprovalDocument
|
||||
{
|
||||
[BsonId]
|
||||
public ObjectId Id { get; init; }
|
||||
|
||||
[BsonElement("tenantId")]
|
||||
public required string TenantId { get; init; }
|
||||
|
||||
[BsonElement("eventId")]
|
||||
public required Guid EventId { get; init; }
|
||||
|
||||
[BsonElement("packId")]
|
||||
public required string PackId { get; init; }
|
||||
|
||||
[BsonElement("kind")]
|
||||
public required string Kind { get; init; }
|
||||
|
||||
[BsonElement("decision")]
|
||||
public required string Decision { get; init; }
|
||||
|
||||
[BsonElement("actor")]
|
||||
public required string Actor { get; init; }
|
||||
|
||||
[BsonElement("issuedAt")]
|
||||
public required DateTimeOffset IssuedAt { get; init; }
|
||||
|
||||
[BsonElement("policyId")]
|
||||
public string? PolicyId { get; init; }
|
||||
|
||||
[BsonElement("policyVersion")]
|
||||
public string? PolicyVersion { get; init; }
|
||||
|
||||
[BsonElement("resumeToken")]
|
||||
public string? ResumeToken { get; init; }
|
||||
|
||||
[BsonElement("summary")]
|
||||
public string? Summary { get; init; }
|
||||
|
||||
[BsonElement("labels")]
|
||||
public Dictionary<string, string>? Labels { get; init; }
|
||||
|
||||
[BsonElement("createdAt")]
|
||||
public required DateTimeOffset CreatedAt { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Storage.Mongo.Internal;
|
||||
|
||||
namespace StellaOps.Notify.Storage.Mongo.Migrations;
|
||||
|
||||
internal sealed class EnsurePackApprovalsCollectionMigration : INotifyMongoMigration
|
||||
{
|
||||
private readonly ILogger<EnsurePackApprovalsCollectionMigration> _logger;
|
||||
|
||||
public EnsurePackApprovalsCollectionMigration(ILogger<EnsurePackApprovalsCollectionMigration> logger)
|
||||
=> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
public string Id => "20251117_pack_approvals_collection_v1";
|
||||
|
||||
public async ValueTask ExecuteAsync(NotifyMongoContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
var target = context.Options.PackApprovalsCollection;
|
||||
|
||||
var cursor = await context.Database
|
||||
.ListCollectionNamesAsync(cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var existing = await cursor.ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (existing.Contains(target, StringComparer.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Creating pack approvals collection '{Collection}'.", target);
|
||||
await context.Database.CreateCollectionAsync(target, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Notify.Storage.Mongo.Internal;
|
||||
|
||||
namespace StellaOps.Notify.Storage.Mongo.Migrations;
|
||||
|
||||
internal sealed class EnsurePackApprovalsIndexesMigration : INotifyMongoMigration
|
||||
{
|
||||
public string Id => "20251117_pack_approvals_indexes_v1";
|
||||
|
||||
public async ValueTask ExecuteAsync(NotifyMongoContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
var collection = context.Database.GetCollection<BsonDocument>(context.Options.PackApprovalsCollection);
|
||||
|
||||
var unique = new CreateIndexModel<BsonDocument>(
|
||||
Builders<BsonDocument>.IndexKeys
|
||||
.Ascending("tenantId")
|
||||
.Ascending("packId")
|
||||
.Ascending("eventId"),
|
||||
new CreateIndexOptions
|
||||
{
|
||||
Name = "tenant_pack_event",
|
||||
Unique = true
|
||||
});
|
||||
|
||||
await collection.Indexes.CreateOneAsync(unique, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var issuedAt = new CreateIndexModel<BsonDocument>(
|
||||
Builders<BsonDocument>.IndexKeys
|
||||
.Ascending("tenantId")
|
||||
.Descending("issuedAt"),
|
||||
new CreateIndexOptions
|
||||
{
|
||||
Name = "tenant_issuedAt"
|
||||
});
|
||||
|
||||
await collection.Indexes.CreateOneAsync(issuedAt, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using StellaOps.Notify.Storage.Mongo.Documents;
|
||||
|
||||
namespace StellaOps.Notify.Storage.Mongo.Repositories;
|
||||
|
||||
public interface INotifyPackApprovalRepository
|
||||
{
|
||||
Task UpsertAsync(PackApprovalDocument document, CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Notify.Storage.Mongo.Documents;
|
||||
using StellaOps.Notify.Storage.Mongo.Internal;
|
||||
|
||||
namespace StellaOps.Notify.Storage.Mongo.Repositories;
|
||||
|
||||
internal sealed class NotifyPackApprovalRepository : INotifyPackApprovalRepository
|
||||
{
|
||||
private readonly IMongoCollection<PackApprovalDocument> _collection;
|
||||
|
||||
public NotifyPackApprovalRepository(NotifyMongoContext context)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
_collection = context.Database.GetCollection<PackApprovalDocument>(context.Options.PackApprovalsCollection);
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(PackApprovalDocument document, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(document);
|
||||
|
||||
var filter = Builders<PackApprovalDocument>.Filter.And(
|
||||
Builders<PackApprovalDocument>.Filter.Eq(x => x.TenantId, document.TenantId),
|
||||
Builders<PackApprovalDocument>.Filter.Eq(x => x.PackId, document.PackId),
|
||||
Builders<PackApprovalDocument>.Filter.Eq(x => x.EventId, document.EventId));
|
||||
|
||||
var options = new ReplaceOptions { IsUpsert = true };
|
||||
await _collection.ReplaceOneAsync(filter, document, options, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user