Skip to content

Commit

Permalink
Capitalization Collation Tests (#2387)
Browse files Browse the repository at this point in the history
## Why make this change?

Solves issue #2350, to add collation tests related to capitalization.

## What is this change?

Added collation tests related to case sensitivity for `MSSQL`, `MYSQL`,
& `POSTGRESQL` by creating a new `GraphQLCollationTests` file under
`SQLTests` that will have all the tests related to changes in collations
for SQL databases.

## How was this tested?

- [X] Integration Tests
- [ ] Unit Tests

---------

Co-authored-by: Ruben Cerna <[email protected]>
  • Loading branch information
RubenCerna2079 and Ruben Cerna authored Oct 11, 2024
1 parent c696cba commit d9fd18c
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Azure.DataApiBuilder.Service.Tests.SqlTests.GraphQLCollationTests
{
[TestClass]
public class GraphQLCollationTestBase : SqlTestBase
{
#region Tests

/// <summary>
/// Compares SQL Database Query with GraphQL Query
/// To ensure that GraphQL is working as expected with case sensitive collations
/// </summary>
public async Task TestQueryingWithCaseSensitiveCollation(string objectType, string fieldName, string dbQuery, string defaultCollationQuery, string newCollationQuery)
{
string graphQLQueryName = objectType;
string graphQLQuery = @"
query { " +
objectType + @" (orderBy: {" + fieldName + @": ASC" + @"}) {
items { "
+ fieldName + @"
}
}
}
";

//Change collation to be case sensitive before executing GraphQL test
await GetDatabaseResultAsync(newCollationQuery);
JsonElement actual = await ExecuteGraphQLRequestAsync(graphQLQuery, graphQLQueryName, isAuthenticated: true);

//Change collation back to default before executing expected test
await GetDatabaseResultAsync(defaultCollationQuery);
string expected = await GetDatabaseResultAsync(dbQuery);

SqlTestHelper.PerformTestEqualJsonStrings(expected, actual.GetProperty("items").ToString());
}
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Azure.DataApiBuilder.Service.Tests.SqlTests.GraphQLCollationTests
{
/// <summary>
/// Test GraphQL Collations validating proper operations.
/// </summary>
[TestClass, TestCategory(TestCategory.MSSQL)]
public class MsSqlGraphQLCollationTests : GraphQLCollationTestBase
{
//Collation setting for database
private const string DEFAULT_COLLATION = "Latin1_General_100_CI_AI_SC_UTF8";
private const string CASE_SENSITIVE_COLLATION = "Latin1_General_100_CS_AI_SC_UTF8";

/// <summary>
/// Set the database engine for the tests
/// </summary>
[ClassInitialize]
public static async Task SetupAsync(TestContext context)
{
DatabaseEngine = TestCategory.MSSQL;
await InitializeTestFixture();
}

#region Tests
/// <summary>
/// MsSql Collation Tests to ensure that GraphQL is working properly when there is a change in case sensitivity on the database
/// </summary>
[DataTestMethod]
[DataRow("comics", "title", @"SELECT title FROM comics ORDER BY title ASC FOR JSON PATH, INCLUDE_NULL_VALUES")]
[DataRow("authors", "name", @"SELECT name FROM authors ORDER BY name ASC FOR JSON PATH, INCLUDE_NULL_VALUES")]
[DataRow("fungi", "habitat", @"SELECT habitat FROM fungi ORDER BY habitat ASC FOR JSON PATH, INCLUDE_NULL_VALUES")]
public async Task MsSqlCaseSensitiveResultQuery(string objectType, string fieldName, string dbQuery)
{
string defaultCollationQuery = MsSqlCollationQuery(objectType, fieldName, DEFAULT_COLLATION);
string newCollationQuery = MsSqlCollationQuery(objectType, fieldName, CASE_SENSITIVE_COLLATION);
await TestQueryingWithCaseSensitiveCollation(objectType, fieldName, dbQuery, defaultCollationQuery, newCollationQuery);
}

/// <summary>
/// Creates collation query for a specific column on a table in the database for MsSql
/// </summary>
private static string MsSqlCollationQuery(string table, string column, string newCollation)
{
string dbQuery = @"
ALTER TABLE dbo." + table + @"
ALTER COLUMN " + column + @" varchar(max) COLLATE " + newCollation;
return dbQuery;
}
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Azure.DataApiBuilder.Service.Tests.SqlTests.GraphQLCollationTests
{

[TestClass, TestCategory(TestCategory.MYSQL)]
public class MySqlGraphQLCollationTests : GraphQLCollationTestBase
{
//Collation setting for database
private const string DEFAULT_COLLATION = "utf8mb4_0900_ai_ci";
private const string CASE_SENSITIVE_COLLATION = "utf8mb4_0900_as_cs";

/// <summary>
/// Set the database engine for the tests
/// </summary>
[ClassInitialize]
public static async Task SetupAsync(TestContext context)
{
DatabaseEngine = TestCategory.MYSQL;
await InitializeTestFixture();
}

#region Tests
/// <summary>
/// MySql Collation Tests to ensure that GraphQL is working properly when there is a change in case sensitivity on the database
/// </summary>
[DataTestMethod]
[DataRow("comics", "title", @"SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT('title', `subq1`.`title`)), '[]') AS `data` FROM ( SELECT `table0`.`title` AS `title` FROM `comics` AS `table0` WHERE 1 = 1 ORDER BY `table0`.`title` ASC LIMIT 100 ) AS `subq1`")]
[DataRow("authors", "name", @"SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT('name', `subq1`.`name`)), '[]') AS `data` FROM ( SELECT `table0`.`name` AS `name` FROM `authors` AS `table0` WHERE 1 = 1 ORDER BY `table0`.`name` ASC LIMIT 100 ) AS `subq1`")]
[DataRow("fungi", "habitat", @"SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT('habitat', `subq1`.`habitat`)), '[]') AS `data` FROM ( SELECT `table0`.`habitat` AS `habitat` FROM `fungi` AS `table0` WHERE 1 = 1 ORDER BY `table0`.`habitat` ASC LIMIT 100 ) AS `subq1`")]

public async Task MySqlCaseSensitiveResultQuery(string objectType, string fieldName, string dbQuery)
{
string defaultCollationQuery = MySqlCollationQuery(objectType, fieldName, DEFAULT_COLLATION);
string newCollationQuery = MySqlCollationQuery(objectType, fieldName, CASE_SENSITIVE_COLLATION);
await TestQueryingWithCaseSensitiveCollation(objectType, fieldName, dbQuery, defaultCollationQuery, newCollationQuery);
}

/// <summary>
/// Creates collation query for a specific column on a table in the database for MySql
/// </summary>
private static string MySqlCollationQuery(string table, string column, string newCollation)
{
string dbQuery = @"
ALTER TABLE " + table + @"
MODIFY COLUMN " + column + @" text
CHARACTER SET utf8mb4 COLLATE " + newCollation;
return dbQuery;
}
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Azure.DataApiBuilder.Service.Tests.SqlTests.GraphQLCollationTests
{

[TestClass, TestCategory(TestCategory.POSTGRESQL)]
public class PostgreSqlGraphQLCollationTests : GraphQLCollationTestBase
{
//Collation setting for database
private const string DEFAULT_COLLATION = "pg_catalog.\"default\"";
private const string CASE_INSENSITIVE_COLLATION = "pg_catalog.\"en-US-u-va-posix-x-icu\"";

/// <summary>
/// Set the database engine for tests
/// </summary>
[ClassInitialize]
public static async Task SetupAsync(TestContext context)
{
DatabaseEngine = TestCategory.POSTGRESQL;
await InitializeTestFixture();
}

#region Tests
/// <summary>
/// Postgres Collation Tests to ensure that GraphQL is working properly when there is a change in case sensitivity on the database
/// </summary>
[DataTestMethod]
[DataRow("comics", "title", @"SELECT json_agg(to_jsonb(table0)) FROM (SELECT title FROM comics ORDER BY title asc) as table0")]
[DataRow("authors", "name", @"SELECT json_agg(to_jsonb(table0)) FROM (SELECT name FROM authors ORDER BY name asc) as table0")]
[DataRow("fungi", "habitat", @"SELECT json_agg(to_jsonb(table0)) FROM (SELECT habitat FROM fungi ORDER BY habitat asc) as table0")]
public async Task PostgresCaseSensitiveResultQuery(string objectType, string fieldName, string dbQuery)
{
string defaultCollationQuery = PostgresCollationQuery(objectType, fieldName, DEFAULT_COLLATION);
string newCollationQuery = PostgresCollationQuery(objectType, fieldName, CASE_INSENSITIVE_COLLATION);
await TestQueryingWithCaseSensitiveCollation(objectType, fieldName, dbQuery, defaultCollationQuery, newCollationQuery);
}

/// <summary>
/// Creates collation query for a specific column on a table in the database for Postgres
/// </summary>
private static string PostgresCollationQuery(string table, string column, string newCollation)
{
string dbQuery = @"
ALTER TABLE " + table + @"
ALTER COLUMN " + column + @" TYPE text
COLLATE " + newCollation;
return dbQuery;
}
#endregion
}
}

0 comments on commit d9fd18c

Please sign in to comment.