using System; using System.Text.Json.Nodes; namespace StellaOps.Notify.Models.Tests; public sealed class NotifySchemaMigrationTests { [Fact] public void UpgradeRuleAddsSchemaVersionWhenMissing() { var json = JsonNode.Parse( """ { "ruleId": "rule-legacy", "tenantId": "tenant-1", "name": "legacy", "enabled": true, "match": { "eventKinds": ["scanner.report.ready"] }, "actions": [ { "actionId": "send", "channel": "email:legacy", "enabled": true } ], "createdAt": "2025-10-18T00:00:00Z", "updatedAt": "2025-10-18T00:00:00Z" } """)!; var rule = NotifySchemaMigration.UpgradeRule(json); Assert.Equal(NotifySchemaVersions.Rule, rule.SchemaVersion); Assert.Equal("rule-legacy", rule.RuleId); } [Fact] public void UpgradeRuleThrowsOnUnknownSchema() { var json = JsonNode.Parse( """ { "schemaVersion": "notify.rule@2", "ruleId": "rule-future", "tenantId": "tenant-1", "name": "future", "enabled": true, "match": { "eventKinds": ["scanner.report.ready"] }, "actions": [ { "actionId": "send", "channel": "email:soc", "enabled": true } ], "createdAt": "2025-10-18T00:00:00Z", "updatedAt": "2025-10-18T00:00:00Z" } """)!; var exception = Assert.Throws(() => NotifySchemaMigration.UpgradeRule(json)); Assert.Contains("notify rule schema version", exception.Message, StringComparison.Ordinal); } [Fact] public void UpgradeChannelDefaultsMissingVersion() { var json = JsonNode.Parse( """ { "channelId": "channel-email", "tenantId": "tenant-1", "name": "email:soc", "type": "email", "config": { "secretRef": "ref://notify/channels/email/soc" }, "enabled": true, "createdAt": "2025-10-18T00:00:00Z", "updatedAt": "2025-10-18T00:00:00Z" } """)!; var channel = NotifySchemaMigration.UpgradeChannel(json); Assert.Equal(NotifySchemaVersions.Channel, channel.SchemaVersion); Assert.Equal("channel-email", channel.ChannelId); } [Fact] public void UpgradeTemplateDefaultsMissingVersion() { var json = JsonNode.Parse( """ { "templateId": "tmpl-slack-concise", "tenantId": "tenant-1", "channelType": "slack", "key": "concise", "locale": "en-us", "body": "{{summary}}", "renderMode": "markdown", "format": "slack", "createdAt": "2025-10-18T00:00:00Z", "updatedAt": "2025-10-18T00:00:00Z" } """)!; var template = NotifySchemaMigration.UpgradeTemplate(json); Assert.Equal(NotifySchemaVersions.Template, template.SchemaVersion); Assert.Equal("tmpl-slack-concise", template.TemplateId); } }