Files

95 lines
4.2 KiB
C#

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
{
/// <summary>
/// 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.
/// </summary>
[ExcludeFromCodeCoverage]
[TestFixture, Category("Integration"), Category("CCI")]
public class StrategicOpportunityGLQueryBuilderIntegrationTests : IntegrationTestBase
{
private StrategicOpportunityGLDetailQueryBuilder _queryBuilder;
private static readonly List<int> DepartmentIds = [1];
private static readonly List<int> RevenueAccountIds = [1];
private static readonly List<int> ExpenseAccountIds = [2];
private static readonly List<int> 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<dynamic>($"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<dynamic>($"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<dynamic>($"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<dynamic>($"EXPLAIN {query}", nameof(BuildDeleteQuery_WithOpportunityId_IsValidSnowflakeSql));
await act.Should().NotThrowAsync("the generated DELETE SQL should be valid Snowflake syntax");
}
}
}