using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Datastore; using NzbDrone.Core.Music; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Datastore { [TestFixture] public class WhereBuilderPostgresFixture : CoreTest { private WhereBuilderPostgres _subject; [OneTimeSetUp] public void MapTables() { // Generate table mapping Mocker.Resolve(); } private WhereBuilderPostgres Where(Expression> filter) { return new WhereBuilderPostgres(filter, true, 0); } private WhereBuilderPostgres WhereMetadata(Expression> filter) { return new WhereBuilderPostgres(filter, true, 0); } [Test] public void where_equal_const() { _subject = Where(x => x.Id == 10); _subject.ToString().Should().Be($"(\"Artists\".\"Id\" = @Clause1_P1)"); _subject.Parameters.Get("Clause1_P1").Should().Be(10); } [Test] public void where_equal_variable() { var id = 10; _subject = Where(x => x.Id == id); _subject.ToString().Should().Be($"(\"Artists\".\"Id\" = @Clause1_P1)"); _subject.Parameters.Get("Clause1_P1").Should().Be(id); } [Test] public void where_equal_property() { var artist = new Artist { Id = 10 }; _subject = Where(x => x.Id == artist.Id); _subject.Parameters.ParameterNames.Should().HaveCount(1); _subject.ToString().Should().Be($"(\"Artists\".\"Id\" = @Clause1_P1)"); _subject.Parameters.Get("Clause1_P1").Should().Be(artist.Id); } [Test] public void where_equal_lazy_property() { _subject = Where(x => x.QualityProfile.Value.Id == 1); _subject.Parameters.ParameterNames.Should().HaveCount(1); _subject.ToString().Should().Be($"(\"QualityProfiles\".\"Id\" = @Clause1_P1)"); _subject.Parameters.Get("Clause1_P1").Should().Be(1); } [Test] public void where_throws_without_concrete_condition_if_requiresConcreteCondition() { Expression> filter = (x, y) => x.Id == y.Id; _subject = new WhereBuilderPostgres(filter, true, 0); Assert.Throws(() => _subject.ToString()); } [Test] public void where_allows_abstract_condition_if_not_requiresConcreteCondition() { Expression> filter = (x, y) => x.Id == y.Id; _subject = new WhereBuilderPostgres(filter, false, 0); _subject.ToString().Should().Be($"(\"Artists\".\"Id\" = \"Artists\".\"Id\")"); } [Test] public void where_string_is_null() { _subject = Where(x => x.CleanName == null); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" IS NULL)"); } [Test] public void where_string_is_null_value() { string imdb = null; _subject = Where(x => x.CleanName == imdb); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" IS NULL)"); } [Test] public void where_equal_null_property() { var artist = new Artist { CleanName = null }; _subject = Where(x => x.CleanName == artist.CleanName); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" IS NULL)"); } [Test] public void where_column_contains_string() { var test = "small"; _subject = Where(x => x.CleanName.Contains(test)); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" ILIKE '%' || @Clause1_P1 || '%')"); _subject.Parameters.Get("Clause1_P1").Should().Be(test); } [Test] public void where_string_contains_column() { var test = "small"; _subject = Where(x => test.Contains(x.CleanName)); _subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"Artists\".\"CleanName\" || '%')"); _subject.Parameters.Get("Clause1_P1").Should().Be(test); } [Test] public void where_column_starts_with_string() { var test = "small"; _subject = Where(x => x.CleanName.StartsWith(test)); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" ILIKE @Clause1_P1 || '%')"); _subject.Parameters.Get("Clause1_P1").Should().Be(test); } [Test] public void where_column_ends_with_string() { var test = "small"; _subject = Where(x => x.CleanName.EndsWith(test)); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" ILIKE '%' || @Clause1_P1)"); _subject.Parameters.Get("Clause1_P1").Should().Be(test); } [Test] public void where_in_list() { var list = new List { 1, 2, 3 }; _subject = Where(x => list.Contains(x.Id)); _subject.ToString().Should().Be($"(\"Artists\".\"Id\" = ANY (('{{1, 2, 3}}')))"); } [Test] public void where_in_list_2() { var list = new List { 1, 2, 3 }; _subject = Where(x => x.CleanName == "test" && list.Contains(x.Id)); _subject.ToString().Should().Be($"((\"Artists\".\"CleanName\" = @Clause1_P1) AND (\"Artists\".\"Id\" = ANY (('{{1, 2, 3}}'))))"); } [Test] public void where_in_string_list() { var list = new List { "first", "second", "third" }; _subject = Where(x => list.Contains(x.CleanName)); _subject.ToString().Should().Be($"(\"Artists\".\"CleanName\" = ANY (@Clause1_P1))"); } [Test] public void where_in_string_list_column() { _subject = WhereMetadata(x => x.OldForeignArtistIds.Contains("foreignId")); _subject.ToString().Should().Be($"(\"ArtistMetadata\".\"OldForeignArtistIds\" ILIKE '%' || @Clause1_P1 || '%')"); } [Test] public void enum_as_int() { _subject = WhereMetadata(x => x.Status == ArtistStatusType.Continuing); _subject.ToString().Should().Be($"(\"ArtistMetadata\".\"Status\" = @Clause1_P1)"); } [Test] public void enum_in_list() { var allowed = new List { ArtistStatusType.Continuing, ArtistStatusType.Ended }; _subject = WhereMetadata(x => allowed.Contains(x.Status)); _subject.ToString().Should().Be($"(\"ArtistMetadata\".\"Status\" = ANY (@Clause1_P1))"); } [Test] public void enum_in_array() { var allowed = new ArtistStatusType[] { ArtistStatusType.Continuing, ArtistStatusType.Ended }; _subject = WhereMetadata(x => allowed.Contains(x.Status)); _subject.ToString().Should().Be($"(\"ArtistMetadata\".\"Status\" = ANY (@Clause1_P1))"); } } }