From 7a419aeb05e4f04100990faaee937a62fdef249f Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 4 Feb 2018 15:17:55 +0100 Subject: [PATCH] Bugfixes for OData --- .../Assets/MongoAssetRepository.cs | 2 +- .../Assets/Visitors/FindExtensions.cs | 16 +- .../Contents/Visitors/FindExtensions.cs | 20 +- .../Assets/Edm/EdmAssetModel.cs | 2 - .../Assets/Edm/EdmAssetQuery.cs | 49 ---- .../Contents/Edm/EdmModelBuilder.cs | 20 +- .../{Contents/Edm => }/EdmModelExtensions.cs | 2 +- .../Views/Account/Consent.cshtml | 6 +- .../Assets/OData/ODataQueryTests.cs | 255 ++++++++++++++++++ .../Contents/OData/ODataQueryTests.cs | 103 +++++-- 10 files changed, 376 insertions(+), 99 deletions(-) delete mode 100644 src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetQuery.cs rename src/Squidex.Domain.Apps.Entities/{Contents/Edm => }/EdmModelExtensions.cs (95%) create mode 100644 tests/Squidex.Domain.Apps.Entities.Tests/Assets/OData/ODataQueryTests.cs diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs index 4c3dd0c16..737c7288c 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs @@ -45,7 +45,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets { try { - var odataQuery = EdmAssetQuery.ParseQuery(query); + var odataQuery = EdmAssetModel.Edm.ParseQuery(query); var filter = FindExtensions.BuildQuery(odataQuery, appId); diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs index 75a32a210..b43fc8f48 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using Microsoft.OData.UriParser; using MongoDB.Bson; using MongoDB.Driver; +using Squidex.Infrastructure; using Squidex.Infrastructure.MongoDb.OData; namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors @@ -17,10 +18,21 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors public static class FindExtensions { private static readonly FilterDefinitionBuilder Filter = Builders.Filter; + private static readonly PropertyCalculator PropertyCalculator = propertyNames => + { + if (propertyNames.Length > 0) + { + propertyNames[0] = propertyNames[0].ToPascalCase(); + } + + var propertyName = string.Join(".", propertyNames); + + return propertyName; + }; public static IFindFluent AssetSort(this IFindFluent cursor, ODataUriParser query) { - var sort = query.BuildSort(); + var sort = query.BuildSort(PropertyCalculator); return sort != null ? cursor.Sort(sort) : cursor.SortByDescending(x => x.LastModified); } @@ -43,7 +55,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors Filter.Eq(x => x.IsDeleted, false) }; - var filter = query.BuildFilter(null, false); + var filter = query.BuildFilter(PropertyCalculator, false); if (filter.Filter != null) { diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs index 72c9bb682..c4ca769b6 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs @@ -8,7 +8,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Microsoft.OData.UriParser; +using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.GenerateEdmSchema; @@ -21,11 +23,20 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors { private static readonly FilterDefinitionBuilder Filter = Builders.Filter; + private static readonly Dictionary PropertyMap = + typeof(MongoContentEntity).GetProperties() + .ToDictionary(x => x.Name, x => x.GetCustomAttribute()?.ElementName ?? x.Name, StringComparer.OrdinalIgnoreCase); + + static FindExtensions() + { + PropertyMap["Data"] = "do"; + } + public static PropertyCalculator CreatePropertyCalculator(Schema schema) { return propertyNames => { - if (propertyNames.Length == 3) + if (propertyNames.Length > 1) { var edmName = propertyNames[1].UnescapeEdmField(); @@ -37,7 +48,12 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors propertyNames[1] = field.Id.ToString(); } - var propertyName = $"do.{string.Join(".", propertyNames.Skip(1))}"; + if (propertyNames.Length > 0) + { + propertyNames[0] = PropertyMap[propertyNames[0]]; + } + + var propertyName = string.Join(".", propertyNames); return propertyName; }; diff --git a/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetModel.cs b/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetModel.cs index 32e2f3a53..ffb58c065 100644 --- a/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetModel.cs +++ b/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetModel.cs @@ -18,8 +18,6 @@ namespace Squidex.Domain.Apps.Entities.Assets.Edm { var entityType = new EdmEntityType("Squidex", "Asset"); - entityType.AddStructuralProperty(nameof(IAssetEntity.Id).ToCamelCase(), EdmPrimitiveTypeKind.Guid); - entityType.AddStructuralProperty(nameof(IAssetEntity.AppId).ToCamelCase(), EdmPrimitiveTypeKind.Guid); entityType.AddStructuralProperty(nameof(IAssetEntity.Created).ToCamelCase(), EdmPrimitiveTypeKind.DateTimeOffset); entityType.AddStructuralProperty(nameof(IAssetEntity.CreatedBy).ToCamelCase(), EdmPrimitiveTypeKind.String); entityType.AddStructuralProperty(nameof(IAssetEntity.LastModified).ToCamelCase(), EdmPrimitiveTypeKind.DateTimeOffset); diff --git a/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetQuery.cs b/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetQuery.cs deleted file mode 100644 index db991ec92..000000000 --- a/src/Squidex.Domain.Apps.Entities/Assets/Edm/EdmAssetQuery.cs +++ /dev/null @@ -1,49 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschränkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using System; -using System.Linq; -using Microsoft.OData; -using Microsoft.OData.Edm; -using Microsoft.OData.UriParser; -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Entities.Assets.Edm -{ - public static class EdmAssetQuery - { - public static ODataUriParser ParseQuery(string query) - { - try - { - var model = EdmAssetModel.Edm; - - if (!model.EntityContainer.EntitySets().Any()) - { - return null; - } - - query = query ?? string.Empty; - - var path = model.EntityContainer.EntitySets().First().Path.Path.Split('.').Last(); - - if (query.StartsWith("?", StringComparison.Ordinal)) - { - query = query.Substring(1); - } - - var parser = new ODataUriParser(model, new Uri($"{path}?{query}", UriKind.Relative)); - - return parser; - } - catch (ODataException ex) - { - throw new ValidationException($"Failed to parse query: {ex.Message}", ex); - } - } - } -} diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelBuilder.cs b/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelBuilder.cs index 5a73c8c59..ea8ffbe18 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelBuilder.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelBuilder.cs @@ -44,8 +44,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.Edm { var model = new EdmModel(); - var container = new EdmEntityContainer("Squidex", "Container"); - var schemaType = schema.BuildEdmType(partitionResolver, x => { model.AddElement(x); @@ -54,19 +52,21 @@ namespace Squidex.Domain.Apps.Entities.Contents.Edm }); var entityType = new EdmEntityType("Squidex", schema.Name); - entityType.AddStructuralProperty("data", new EdmComplexTypeReference(schemaType, false)); - entityType.AddStructuralProperty("version", EdmPrimitiveTypeKind.Int32); - entityType.AddStructuralProperty("created", EdmPrimitiveTypeKind.DateTimeOffset); - entityType.AddStructuralProperty("createdBy", EdmPrimitiveTypeKind.String); - entityType.AddStructuralProperty("lastModified", EdmPrimitiveTypeKind.DateTimeOffset); - entityType.AddStructuralProperty("lastModifiedBy", EdmPrimitiveTypeKind.String); + entityType.AddStructuralProperty(nameof(IContentEntity.Created).ToCamelCase(), EdmPrimitiveTypeKind.DateTimeOffset); + entityType.AddStructuralProperty(nameof(IContentEntity.CreatedBy).ToCamelCase(), EdmPrimitiveTypeKind.String); + entityType.AddStructuralProperty(nameof(IContentEntity.LastModified).ToCamelCase(), EdmPrimitiveTypeKind.DateTimeOffset); + entityType.AddStructuralProperty(nameof(IContentEntity.LastModifiedBy).ToCamelCase(), EdmPrimitiveTypeKind.String); + entityType.AddStructuralProperty(nameof(IContentEntity.Version).ToCamelCase(), EdmPrimitiveTypeKind.Int32); + entityType.AddStructuralProperty(nameof(IContentEntity.Data).ToCamelCase(), new EdmComplexTypeReference(schemaType, false)); + + var container = new EdmEntityContainer("Squidex", "Container"); + + container.AddEntitySet("ContentSet", entityType); model.AddElement(container); model.AddElement(schemaType); model.AddElement(entityType); - container.AddEntitySet("ContentSet", entityType); - return model; } } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelExtensions.cs b/src/Squidex.Domain.Apps.Entities/EdmModelExtensions.cs similarity index 95% rename from src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelExtensions.cs rename to src/Squidex.Domain.Apps.Entities/EdmModelExtensions.cs index 03c97b8f7..afb38c598 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Edm/EdmModelExtensions.cs +++ b/src/Squidex.Domain.Apps.Entities/EdmModelExtensions.cs @@ -10,7 +10,7 @@ using System.Linq; using Microsoft.OData.Edm; using Microsoft.OData.UriParser; -namespace Squidex.Domain.Apps.Entities.Contents.Edm +namespace Squidex.Domain.Apps.Entities { public static class EdmModelExtensions { diff --git a/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml b/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml index 083e78ffe..7e6a94ae2 100644 --- a/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml +++ b/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml @@ -20,14 +20,14 @@
-

Automated E-Mails

+

Automated E-Mails (Optional)

- I understand and agree that Squidex sends Emails to imform me about new features, breaking changes and downtimes. + I understand and agree that Squidex sends e-mails to inform me about new features, breaking changes and downtimes.
@@ -49,7 +49,7 @@ I understand and agree that Squidex has integrated Google Analytics (with the anonymizer function). Google Analytics is a web analytics service to gather and analyse data about the behavior of users.

- I have read the Privacy Policies. + I have read the privacy policies and understand them.

diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Assets/OData/ODataQueryTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/OData/ODataQueryTests.cs new file mode 100644 index 000000000..6a0a6be00 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/OData/ODataQueryTests.cs @@ -0,0 +1,255 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using FakeItEasy; +using Microsoft.OData.Edm; +using MongoDB.Bson.Serialization; +using MongoDB.Driver; +using Squidex.Domain.Apps.Entities.Assets.Edm; +using Squidex.Domain.Apps.Entities.MongoDb.Assets; +using Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors; +using Squidex.Infrastructure.MongoDb; +using Squidex.Infrastructure.MongoDb.OData; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Assets.OData +{ + public class ODataQueryTests + { + private readonly IBsonSerializerRegistry registry = BsonSerializer.SerializerRegistry; + private readonly IBsonSerializer serializer = BsonSerializer.SerializerRegistry.GetSerializer(); + private readonly IEdmModel edmModel = EdmAssetModel.Edm; + + static ODataQueryTests() + { + InstantSerializer.Register(); + } + + [Fact] + public void Should_parse_query() + { + var parser = edmModel.ParseQuery("$filter=lastModifiedBy eq 'Sebastian'"); + + Assert.NotNull(parser); + } + + [Fact] + public void Should_make_query_with_lastModified() + { + var i = F("$filter=lastModified eq 1988-01-19T12:00:00Z"); + var o = C("{ 'LastModified' : ISODate('1988-01-19T12:00:00Z') }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_lastModifiedBy() + { + var i = F("$filter=lastModifiedBy eq 'Me'"); + var o = C("{ 'LastModifiedBy' : 'Me' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_created() + { + var i = F("$filter=created eq 1988-01-19T12:00:00Z"); + var o = C("{ 'Created' : ISODate('1988-01-19T12:00:00Z') }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_createdBy() + { + var i = F("$filter=createdBy eq 'Me'"); + var o = C("{ 'CreatedBy' : 'Me' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_version() + { + var i = F("$filter=version eq 0"); + var o = C("{ 'Version' : NumberLong(0) }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_fileName() + { + var i = F("$filter=fileName eq 'Logo.png'"); + var o = C("{ 'FileName' : 'Logo.png' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_fileSize() + { + var i = F("$filter=fileSize eq 1024"); + var o = C("{ 'FileSize' : NumberLong(1024) }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_fileVersion() + { + var i = F("$filter=fileVersion eq 2"); + var o = C("{ 'FileVersion' : NumberLong(2) }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_isImage() + { + var i = F("$filter=isImage eq true"); + var o = C("{ 'IsImage' : true }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_mimeType() + { + var i = F("$filter=mimeType eq 'text/json'"); + var o = C("{ 'MimeType' : 'text/json' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_pixelHeight() + { + var i = F("$filter=pixelHeight eq 600"); + var o = C("{ 'PixelHeight' : 600 }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_pixelWidth() + { + var i = F("$filter=pixelWidth eq 600"); + var o = C("{ 'PixelWidth' : 600 }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_orderby_with_single_field() + { + var i = S("$orderby=lastModified desc"); + var o = C("{ 'LastModified' : -1 }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_orderby_with_multiple_field() + { + var i = S("$orderby=lastModified, lastModifiedBy desc"); + var o = C("{ 'LastModified' : 1, 'LastModifiedBy' : -1 }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_top_statement() + { + var parser = edmModel.ParseQuery("$top=3"); + var cursor = A.Fake>(); + + cursor.AssetTake(parser); + + A.CallTo(() => cursor.Limit(3)).MustHaveHappened(); + } + + [Fact] + public void Should_make_top_statement_with_limit() + { + var parser = edmModel.ParseQuery("$top=300"); + var cursor = A.Fake>(); + + cursor.AssetTake(parser); + + A.CallTo(() => cursor.Limit(200)).MustHaveHappened(); + } + + [Fact] + public void Should_make_top_statement_with_default_value() + { + var parser = edmModel.ParseQuery(string.Empty); + var cursor = A.Fake>(); + + cursor.AssetTake(parser); + + A.CallTo(() => cursor.Limit(20)).MustHaveHappened(); + } + + [Fact] + public void Should_make_skip_statement() + { + var parser = edmModel.ParseQuery("$skip=3"); + var cursor = A.Fake>(); + + cursor.AssetSkip(parser); + + A.CallTo(() => cursor.Skip(3)).MustHaveHappened(); + } + + [Fact] + public void Should_make_skip_statement_with_default_value() + { + var parser = edmModel.ParseQuery(string.Empty); + var cursor = A.Fake>(); + + cursor.AssetSkip(parser); + + A.CallTo(() => cursor.Skip(A.Ignored)).MustNotHaveHappened(); + } + + private static string C(string value) + { + return value.Replace('\'', '"'); + } + + private string S(string value) + { + var parser = edmModel.ParseQuery(value); + var cursor = A.Fake>(); + + var i = string.Empty; + + A.CallTo(() => cursor.Sort(A>.Ignored)) + .Invokes((SortDefinition sortDefinition) => + { + i = sortDefinition.Render(serializer, registry).ToString(); + }); + + cursor.AssetSort(parser); + + return i; + } + + private string F(string value) + { + var parser = edmModel.ParseQuery(value); + + var query = + parser.BuildFilter() + .Filter.Render(serializer, registry).ToString(); + + return query; + } + } +} \ No newline at end of file diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/OData/ODataQueryTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/OData/ODataQueryTests.cs index 06f8f0ade..1c29ae240 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/OData/ODataQueryTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/OData/ODataQueryTests.cs @@ -86,6 +86,51 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData Assert.NotNull(parser); } + [Fact] + public void Should_make_query_with_created() + { + var i = F("$filter=created eq 1988-01-19T12:00:00Z"); + var o = C("{ 'ct' : ISODate('1988-01-19T12:00:00Z') }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_createdBy() + { + var i = F("$filter=createdBy eq 'Me'"); + var o = C("{ 'cb' : 'Me' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_lastModified() + { + var i = F("$filter=lastModified eq 1988-01-19T12:00:00Z"); + var o = C("{ 'mt' : ISODate('1988-01-19T12:00:00Z') }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_lastModifiedBy() + { + var i = F("$filter=lastModifiedBy eq 'Me'"); + var o = C("{ 'mb' : 'Me' }"); + + Assert.Equal(o, i); + } + + [Fact] + public void Should_make_query_with_version() + { + var i = F("$filter=version eq 0"); + var o = C("{ 'vs' : 0 }"); + + Assert.Equal(o, i); + } + [Fact] public void Should_make_query_with_underscore_field() { @@ -96,7 +141,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_not_operator() + public void Should_make_query_with_not() { var i = F("$filter=not endswith(data/firstName/de, 'Sebastian')"); var o = C("{ 'do.1.de' : { '$not' : /Sebastian$/i } }"); @@ -105,7 +150,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_starts_with_query() + public void Should_make_query_with_startswith() { var i = F("$filter=startswith(data/firstName/de, 'Sebastian')"); var o = C("{ 'do.1.de' : /^Sebastian/i }"); @@ -114,7 +159,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_ends_with_query() + public void Should_make_query_with_endswith() { var i = F("$filter=endswith(data/firstName/de, 'Sebastian')"); var o = C("{ 'do.1.de' : /Sebastian$/i }"); @@ -123,7 +168,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_contains_query() + public void Should_make_query_with_cointains() { var i = F("$filter=contains(data/firstName/de, 'Sebastian')"); var o = C("{ 'do.1.de' : /Sebastian/i }"); @@ -132,7 +177,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_contains_query_with_equals() + public void Should_make_query_with_equals() { var i = F("$filter=contains(data/firstName/de, 'Sebastian') eq true"); var o = C("{ 'do.1.de' : /Sebastian/i }"); @@ -141,7 +186,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_negated_contains_query_with_equals() + public void Should_make_query_wih_equals_to_false() { var i = F("$filter=contains(data/firstName/de, 'Sebastian') eq false"); var o = C("{ 'do.1.de' : { '$not' : /Sebastian/i } }"); @@ -150,7 +195,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_negated_contains_query_and_other() + public void Should_make_query_with_conjunction_and_contains() { var i = F("$filter=contains(data/firstName/de, 'Sebastian') eq false and data/isAdmin/iv eq true"); var o = C("{ 'do.1.de' : { '$not' : /Sebastian/i }, 'do.3.iv' : true }"); @@ -159,7 +204,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_string_equals_query() + public void Should_make_query_with_string_equals() { var i = F("$filter=data/firstName/de eq 'Sebastian'"); var o = C("{ 'do.1.de' : 'Sebastian' }"); @@ -168,16 +213,16 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_datetime_equals_query() + public void Should_make_query_with_datetime_equals() { var i = F("$filter=data/birthday/iv eq 1988-01-19T12:00:00Z"); - var o = C("{ 'do.5.iv' : ISODate(\"1988-01-19T12:00:00Z\") }"); + var o = C("{ 'do.5.iv' : ISODate('1988-01-19T12:00:00Z') }"); Assert.Equal(o, i); } [Fact] - public void Should_create_boolean_equals_query() + public void Should_make_query_with_boolean_equals() { var i = F("$filter=data/isAdmin/iv eq true"); var o = C("{ 'do.3.iv' : true }"); @@ -186,7 +231,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_string_not_equals_query() + public void Should_make_query_with_notequals() { var i = F("$filter=data/firstName/de ne 'Sebastian'"); var o = C("{ '$or' : [{ 'do.1.de' : { '$exists' : false } }, { 'do.1.de' : { '$ne' : 'Sebastian' } }] }"); @@ -195,7 +240,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_number_less_than_query() + public void Should_make_query_with_lessthan() { var i = F("$filter=data/age/iv lt 1"); var o = C("{ 'do.4.iv' : { '$lt' : 1.0 } }"); @@ -204,7 +249,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_number_less_equals_query() + public void Should_make_query_with_lessequals() { var i = F("$filter=data/age/iv le 1"); var o = C("{ 'do.4.iv' : { '$lte' : 1.0 } }"); @@ -213,7 +258,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_number_greater_than_query() + public void Should_make_query_with_greaterthan() { var i = F("$filter=data/age/iv gt 1"); var o = C("{ 'do.4.iv' : { '$gt' : 1.0 } }"); @@ -222,7 +267,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_number_greater_equals_query() + public void Should_make_query_with_greaterequals() { var i = F("$filter=data/age/iv ge 1"); var o = C("{ 'do.4.iv' : { '$gte' : 1.0 } }"); @@ -231,7 +276,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_equals_query_for_assets() + public void Should_make_query_with_references_equals() { var i = F("$filter=data/pictures/iv eq 'guid'"); var o = C("{ 'do.6.iv' : 'guid' }"); @@ -240,7 +285,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_equals_query_for_references() + public void Should_make_query_with_assets_equals() { var i = F("$filter=data/friends/iv eq 'guid'"); var o = C("{ 'do.7.iv' : 'guid' }"); @@ -249,7 +294,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_and_query() + public void Should_make_query_with_conjunction() { var i = F("$filter=data/age/iv eq 1 and data/age/iv eq 2"); var o = C("{ '$and' : [{ 'do.4.iv' : 1.0 }, { 'do.4.iv' : 2.0 }] }"); @@ -258,7 +303,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_or_query() + public void Should_make_query_with_disjunction() { var i = F("$filter=data/age/iv eq 1 or data/age/iv eq 2"); var o = C("{ '$or' : [{ 'do.4.iv' : 1.0 }, { 'do.4.iv' : 2.0 }] }"); @@ -267,7 +312,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_full_text_query() + public void Should_make_query_with_full_text() { var i = F("$search=Hello my World"); var o = C("{ '$text' : { '$search' : 'Hello my World' } }"); @@ -276,7 +321,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_create_full_text_query_with_and() + public void Should_make_query_with_full_text_and_multiple_terms() { var i = F("$search=A and B"); var o = C("{ '$text' : { '$search' : 'A and B' } }"); @@ -285,7 +330,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_convert_orderby_with_single_statements() + public void Should_make_orderby_with_single_field() { var i = S("$orderby=data/age/iv desc"); var o = C("{ 'do.4.iv' : -1 }"); @@ -294,7 +339,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_convert_orderby_with_multiple_statements() + public void Should_make_orderby_with_multiple_field() { var i = S("$orderby=data/age/iv, data/firstName/en desc"); var o = C("{ 'do.4.iv' : 1, 'do.1.en' : -1 }"); @@ -303,7 +348,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_set_top() + public void Should_make_top_statement() { var parser = edmModel.ParseQuery("$top=3"); var cursor = A.Fake>(); @@ -314,7 +359,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_set_max_top_if_larger() + public void Should_make_top_statement_with_limit() { var parser = edmModel.ParseQuery("$top=300"); var cursor = A.Fake>(); @@ -325,7 +370,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_set_default_top() + public void Should_make_top_statement_with_default_value() { var parser = edmModel.ParseQuery(string.Empty); var cursor = A.Fake>(); @@ -336,7 +381,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_set_skip() + public void Should_make_skip_statement() { var parser = edmModel.ParseQuery("$skip=3"); var cursor = A.Fake>(); @@ -347,7 +392,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.OData } [Fact] - public void Should_not_set_skip() + public void Should_make_skip_statement_with_default_value() { var parser = edmModel.ParseQuery(string.Empty); var cursor = A.Fake>();