using FluentAssertions; using NUnit.Framework; using Strata.ContinuousImprovement.Biz.StrategicOpportunities.Queries; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Strata.ContinuousImprovement.Biz.Test.Integration.SnowflakeIntegrationTests { /// /// Validates that the SQL generated by StrategicOpportunityGLDetailQueryBuilder /// is syntactically correct and references valid objects in Snowflake. /// Uses EXPLAIN to parse and plan each statement without executing DML. /// [ExcludeFromCodeCoverage] [TestFixture, Category("Integration"), Category("CCI")] public class StrategicOpportunityGLQueryBuilderIntegrationTests : IntegrationTestBase { private StrategicOpportunityGLDetailQueryBuilder _queryBuilder; private static readonly List DepartmentIds = [1]; private static readonly List RevenueAccountIds = [1]; private static readonly List ExpenseAccountIds = [2]; private static readonly List StatisticAccountIds = [3]; private static readonly DateOnly BaselineStart = new(2024, 1, 1); private static readonly DateOnly BaselineEnd = new(2024, 12, 31); [OneTimeSetUp] public void Setup() { _queryBuilder = new StrategicOpportunityGLDetailQueryBuilder(); } [Test] public async Task BuildInsertQuery_FwTable_IsValidSnowflakeSql() { var query = _queryBuilder.BuildInsertQuery( opportunityId: 0, sourceTable: "fw.factglsampled", departmentIds: DepartmentIds, revenueAccountIds: RevenueAccountIds, expenseAccountIds: ExpenseAccountIds, statisticAccountIds: StatisticAccountIds, baselineStart: BaselineStart, baselineEnd: BaselineEnd); var act = async () => await SnowflakeDatabaseContext.QueryAsync($"EXPLAIN {query}", nameof(BuildInsertQuery_FwTable_IsValidSnowflakeSql)); await act.Should().NotThrowAsync("the generated INSERT SQL should be valid Snowflake syntax"); } [Test] public async Task BuildInsertQuery_IntTable_IsValidSnowflakeSql() { var query = _queryBuilder.BuildInsertQuery( opportunityId: 0, sourceTable: "int.factgl", departmentIds: DepartmentIds, revenueAccountIds: RevenueAccountIds, expenseAccountIds: ExpenseAccountIds, statisticAccountIds: StatisticAccountIds, baselineStart: BaselineStart, baselineEnd: BaselineEnd); var act = async () => await SnowflakeDatabaseContext.QueryAsync($"EXPLAIN {query}", nameof(BuildInsertQuery_IntTable_IsValidSnowflakeSql)); await act.Should().NotThrowAsync("the generated INSERT SQL should be valid Snowflake syntax"); } [Test] public async Task BuildMergeQuery_FwTable_IsValidSnowflakeSql() { var query = _queryBuilder.BuildMergeQuery( opportunityId: 0, sourceTable: "fw.factglsampled", departmentIds: DepartmentIds, revenueAccountIds: RevenueAccountIds, expenseAccountIds: ExpenseAccountIds, statisticAccountIds: StatisticAccountIds, trackingStart: new DateOnly(2025, 1, 1), trackingEnd: new DateOnly(2025, 12, 31)); var act = async () => await SnowflakeDatabaseContext.QueryAsync($"EXPLAIN {query}", nameof(BuildMergeQuery_FwTable_IsValidSnowflakeSql)); await act.Should().NotThrowAsync("the generated MERGE SQL should be valid Snowflake syntax"); } [Test] public async Task BuildDeleteQuery_WithOpportunityId_IsValidSnowflakeSql() { var query = _queryBuilder.BuildDeleteQuery(opportunityId: 0); var act = async () => await SnowflakeDatabaseContext.QueryAsync($"EXPLAIN {query}", nameof(BuildDeleteQuery_WithOpportunityId_IsValidSnowflakeSql)); await act.Should().NotThrowAsync("the generated DELETE SQL should be valid Snowflake syntax"); } } }