using SQLInsight.Agent.Hub; using SQLInsight.Contracts; using SQLInsight.Core.Findings; using SQLInsight.Core.Instances; using SQLInsight.Repository; using SQLInsight.Rules.Engine; namespace SQLInsight.Agent.Tests; public class SubmissionBuilderTests { private static readonly DateTimeOffset Now = new(2026, 9, 29, 12, 0, 0, TimeSpan.Zero); private static readonly InstanceInfo Info = new() { ServerName = "SQL01.corp.local", Version = SqlServerVersion.Parse("15.0.4490.9"), ProductLevel = "RTM", ProductUpdateLevel = "CU32", Edition = "Enterprise Edition", EngineEdition = EngineEdition.Enterprise, }; private static readonly StoredFinding Blocking = new() { FindingId = 1, RuleId = "SQLI-BLK-001", Subject = "session: 51", Severity = Severity.High, Title = "Session 51 blokerer", Explanation = "Forklaring", Recommendation = "Anbefaling", FirstSeenAt = Now.UtcDateTime.AddMinutes(-5), Evidence = [ new Evidence("Blokerede sessioner", "3"), new Evidence("Head blockers SQL", "UPDATE dbo.Salaries SET Amount = 100000 WHERE Name = 'Hansen'", Sensitive: true), ], }; private static RuleResult[] Results => [new RuleResult { RuleId = "SQLI-BLK-001", RuleTitle = "t", Outcome = RuleOutcome.Findings }]; [Fact] public void Sensitive_evidence_and_server_name_stay_on_prem_by_default() { var submission = SubmissionBuilder.Build("prod-sql01", Info, Results, [Blocking], new HubOptions(), Now); var evidence = Assert.Single(submission.Findings).Evidence; Assert.Equal("3", evidence[0].Value); Assert.Equal(FindingsSubmission.Redacted, evidence[1].Value); Assert.Null(submission.Instance.ServerName); Assert.Equal("prod-sql01", submission.Instance.InstanceKey); Assert.Equal("SQL Server 2019", submission.Instance.Release); } [Fact] public void Customer_can_allow_sensitive_evidence_and_server_name() { var options = new HubOptions { SendSensitiveEvidence = true, SendServerName = true }; var submission = SubmissionBuilder.Build("prod-sql01", Info, Results, [Blocking], options, Now); Assert.StartsWith("UPDATE dbo.Salaries", submission.Findings[0].Evidence[1].Value, StringComparison.Ordinal); Assert.Equal("SQL01.corp.local", submission.Instance.ServerName); } [Fact] public void Every_submission_has_a_new_id_and_carries_rule_outcomes() { var a = SubmissionBuilder.Build("x", Info, Results, [], new HubOptions(), Now); var b = SubmissionBuilder.Build("x", Info, Results, [], new HubOptions(), Now); Assert.NotEqual(a.SubmissionId, b.SubmissionId); Assert.Equal("Findings", Assert.Single(a.Rules).Outcome); } [Theory] [InlineData(0, 1)] [InlineData(1, 2)] [InlineData(3, 8)] [InlineData(10, 60)] [InlineData(50, 60)] public void Backoff_doubles_up_to_an_hour(int attempts, int minutes) { Assert.Equal(TimeSpan.FromMinutes(minutes), HubSyncService.Backoff(attempts)); } }