Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions QueryKit.IntegrationTests/Tests/AliasCultureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ namespace QueryKit.IntegrationTests.Tests;

using System.Globalization;
using Configuration;
using Exceptions;
using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using SharedTestingHelper.Fakes;
using WebApiTestProject.Entities;

// Like v1.14.2, a query name matches with the case rules of the culture of each parse,
// also when a parse in another culture used the same query name before.
// A query name ignores case with the rules of the invariant culture, so the result does not depend on the culture of the parse.
public class AliasCultureTests : TestBase
{
[Fact]
public async Task query_name_matches_in_en_us_after_a_tr_tr_parse()
public async Task query_name_with_i_matches_its_upper_case_in_tr_tr()
{
// Arrange
var testingServiceScope = new TestingServiceScope();
Expand All @@ -37,10 +35,6 @@ public async Task query_name_matches_in_en_us_after_a_tr_tr_parse()
try
{
CultureInfo.CurrentCulture = new CultureInfo("tr-TR");
var turkish = () => testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, config);
turkish.Should().Throw<UnknownFilterPropertyException>();

CultureInfo.CurrentCulture = new CultureInfo("en-US");
appliedQueryable = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, config);
}
finally
Expand Down
85 changes: 85 additions & 0 deletions QueryKit.IntegrationTests/Tests/PropertyResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,36 @@ public async Task prevented_property_on_the_right_side_is_not_compared()
people.Should().BeEmpty();
}

[Fact]
public async Task prevented_property_on_the_right_side_is_not_compared_when_another_query_name_matches_its_name()
{
// Arrange
var testingServiceScope = new TestingServiceScope();
var title = new Faker().Lorem.Sentence();
var fakePerson = new FakeTestingPersonBuilder()
.WithTitle(title)
.WithFirstName("Same")
.WithLastName("Same")
.WithAge(30)
.Build();
await testingServiceScope.InsertAsync(fakePerson);

var input = $"""Title == "{title}" && (FirstName == LastName || Age > 100)""";
var config = new QueryKitConfiguration(config =>
{
config.Property<TestingPerson>(x => x.FirstName!).HasQueryName("lastname");
config.Property<TestingPerson>(x => x.LastName!).PreventFilter();
});

// Act
var people = await testingServiceScope.DbContext().People
.ApplyQueryKitFilter(input, config)
.ToListAsync();

// Assert
people.Should().BeEmpty();
}

[Fact]
public async Task prevented_property_in_a_list_is_not_filtered_in_any_case()
{
Expand Down Expand Up @@ -358,6 +388,61 @@ public async Task prevented_derived_sort_property_is_not_sorted()
people.Select(x => x.Id).Should().Equal(firstPerson.Id, secondPerson.Id);
}

[Fact]
public async Task query_name_in_a_property_list_is_filtered()
{
// Arrange
var testingServiceScope = new TestingServiceScope();
var title = new Faker().Lorem.Sentence();
var fakePerson = new FakeTestingPersonBuilder()
.WithTitle(title)
.WithFirstName("Paul")
.WithLastName("Other")
.Build();
await testingServiceScope.InsertAsync(fakePerson);

var input = $"""Title == "{title}" && (first, LastName) == "Paul" """;
var config = new QueryKitConfiguration(config =>
{
config.Property<TestingPerson>(x => x.FirstName!).HasQueryName("first");
});

// Act
var people = await testingServiceScope.DbContext().People
.ApplyQueryKitFilter(input, config)
.ToListAsync();

// Assert
people.Should().ContainSingle(x => x.Id == fakePerson.Id);
}

[Fact]
public async Task query_name_in_arithmetic_is_filtered()
{
// Arrange
var testingServiceScope = new TestingServiceScope();
var title = new Faker().Lorem.Sentence();
var fakePerson = new FakeTestingPersonBuilder()
.WithTitle(title)
.WithAge(30)
.Build();
await testingServiceScope.InsertAsync(fakePerson);

var input = $"""Title == "{title}" && (years + 0) > 20""";
var config = new QueryKitConfiguration(config =>
{
config.Property<TestingPerson>(x => x.Age!).HasQueryName("years");
});

// Act
var people = await testingServiceScope.DbContext().People
.ApplyQueryKitFilter(input, config)
.ToListAsync();

// Assert
people.Should().ContainSingle(x => x.Id == fakePerson.Id);
}

[Theory]
[InlineData("first-name")]
[InlineData("_first")]
Expand Down
47 changes: 35 additions & 12 deletions QueryKit.UnitTests/AliasCultureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,63 @@
using FluentAssertions;
using WebApiTestProject.Entities.Recipes;

// Like v1.14.2, an alias matches with the case rules of the culture of each parse,
// A query name ignores case with the rules of the invariant culture, so the result does not depend on the culture of the parse.
// Like v1.14.2, an operator alias matches with the case rules of the culture of each parse,
// also when a parse in another culture used the same alias before.
// Each test uses its own alias, so the result does not depend on the order of the tests.
public class AliasCultureTests
{
[Fact]
public void query_name_matches_in_en_us_after_a_tr_tr_parse()
[Theory]
[InlineData("en-US")]
[InlineData("tr-TR")]
public void query_name_with_i_matches_its_upper_case_with_the_invariant_rules_in_every_culture(string cultureName)
{
var config = new QueryKitConfiguration(settings =>
{
settings.Property<Recipe>(x => x.Rating!).HasQueryName("tipalpha");
});
var input = "TIPALPHA > 3";

var turkish = () => WithCulture("tr-TR", () => FilterParser.ParseFilter<Recipe>(input, config));
turkish.Should().Throw<UnknownFilterPropertyException>();
var filterExpression = WithCulture(cultureName, () => FilterParser.ParseFilter<Recipe>("TIPALPHA > 3", config));

var filterExpression = WithCulture("en-US", () => FilterParser.ParseFilter<Recipe>(input, config));
filterExpression.ToString().Should().Be("x => (x.Rating > 3)");
}

[Fact]
public void query_name_does_not_match_in_tr_tr_after_an_en_us_parse()
[Theory]
[InlineData("en-US", "TIPBETA > 3", "x => (x.Rating > 3)")]
[InlineData("tr-TR", "TIPBETA > 3", "x => (x.Rating > 3)")]
[InlineData("tr-TR", "(TIPBETA, Title) == 3", "x => ((x.Rating == 3) OrElse (x.Title == \"3\"))")]
[InlineData("tr-TR", "TIPBETA desc", null)]
public void query_name_with_i_matches_its_upper_case_in_tr_tr_in_every_syntax(string cultureName, string input, string? expected)
{
var config = new QueryKitConfiguration(settings =>
{
settings.Property<Recipe>(x => x.Rating!).HasQueryName("tipbeta");
});
var input = "TIPBETA > 3";

var filterExpression = WithCulture("en-US", () => FilterParser.ParseFilter<Recipe>(input, config));
filterExpression.ToString().Should().Be("x => (x.Rating > 3)");
if (expected == null)
{
var sortExpressions = WithCulture(cultureName, () => SortParser.ParseSort<Recipe>(input, config));
sortExpressions.Should().ContainSingle();
sortExpressions[0].Expression!.ToString().Should().Contain("x.Rating");
return;
}

var filterExpression = WithCulture(cultureName, () => FilterParser.ParseFilter<Recipe>(input, config));
filterExpression.ToString().Should().Be(expected);
}

[Theory]
[InlineData("tıp", "TIP > 3")]
[InlineData("tip", "TİP > 3")]
public void query_name_does_not_match_with_the_dotted_and_dotless_i_rules_of_tr_tr(string queryName, string input)
{
var config = new QueryKitConfiguration(settings =>
{
settings.Property<Recipe>(x => x.Rating).HasQueryName(queryName);

Check warning on line 61 in QueryKit.UnitTests/AliasCultureTests.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference return.

Check warning on line 61 in QueryKit.UnitTests/AliasCultureTests.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference return.

Check warning on line 61 in QueryKit.UnitTests/AliasCultureTests.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference return.

Check warning on line 61 in QueryKit.UnitTests/AliasCultureTests.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference return.
});

var turkish = () => WithCulture("tr-TR", () => FilterParser.ParseFilter<Recipe>(input, config));

turkish.Should().Throw<UnknownFilterPropertyException>();
}

Expand Down
Loading
Loading