Browse Source

Tests

pull/1/head
Sebastian 9 years ago
parent
commit
973219d164
  1. 11
      src/Squidex.Core/Schemas/DateTimeField.cs
  2. 7
      src/Squidex.Infrastructure.MongoDb/InstantSerializer.cs
  3. 34
      src/Squidex.Read.MongoDb/Contents/Visitors/ConstantVisitor.cs
  4. 21
      src/Squidex.Read.MongoDb/Contents/Visitors/FilterVisitor.cs
  5. 4
      src/Squidex.Read.MongoDb/Contents/Visitors/SchemaExtensions.cs
  6. 49
      tests/Squidex.Read.Tests/MongoDb/Contents/ODataQueryTests.cs

11
src/Squidex.Core/Schemas/DateTimeField.cs

@ -69,19 +69,12 @@ namespace Squidex.Core.Schemas
{ {
jsonProperty.Type = JsonObjectType.String; jsonProperty.Type = JsonObjectType.String;
if (Properties.Editor == DateTimeFieldEditor.Date) jsonProperty.Format = JsonFormatStrings.DateTime;
{
jsonProperty.Format = JsonFormatStrings.Date;
}
else
{
jsonProperty.Format = JsonFormatStrings.DateTime;
}
} }
protected override IEdmTypeReference CreateEdmType() protected override IEdmTypeReference CreateEdmType()
{ {
return EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Date, !Properties.IsRequired); return EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.DateTimeOffset, !Properties.IsRequired);
} }
} }
} }

7
src/Squidex.Infrastructure.MongoDb/InstantSerializer.cs

@ -14,7 +14,7 @@ using NodaTime;
namespace Squidex.Infrastructure.MongoDb namespace Squidex.Infrastructure.MongoDb
{ {
public sealed class InstantSerializer : SerializerBase<Instant> public sealed class InstantSerializer : SerializerBase<Instant>, IBsonPolymorphicSerializer
{ {
private static bool isRegistered; private static bool isRegistered;
private static readonly object LockObject = new object(); private static readonly object LockObject = new object();
@ -38,6 +38,11 @@ namespace Squidex.Infrastructure.MongoDb
return false; return false;
} }
public bool IsDiscriminatorCompatibleWithObjectSerializer
{
get { return true; }
}
public override Instant Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) public override Instant Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{ {
var value = context.Reader.ReadDateTime(); var value = context.Reader.ReadDateTime();

34
src/Squidex.Read.MongoDb/Contents/Visitors/ConstantVisitor.cs

@ -6,8 +6,16 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
using Microsoft.OData.Core.UriParser.Semantic; using Microsoft.OData.Core.UriParser.Semantic;
using Microsoft.OData.Core.UriParser.Visitors; using Microsoft.OData.Core.UriParser.Visitors;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Library;
using NodaTime;
using NodaTime.Text;
// ReSharper disable ConvertIfStatementToReturnStatement
// ReSharper disable InvertIf
namespace Squidex.Read.MongoDb.Contents.Visitors namespace Squidex.Read.MongoDb.Contents.Visitors
{ {
@ -24,6 +32,32 @@ namespace Squidex.Read.MongoDb.Contents.Visitors
return node.Accept(Instance); return node.Accept(Instance);
} }
public override object Visit(ConvertNode nodeIn)
{
var booleanType = EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Boolean);
if (nodeIn.TypeReference.Definition == booleanType)
{
return bool.Parse(Visit(nodeIn.Source).ToString());
}
var dateTimeType = EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.DateTimeOffset);
if (nodeIn.TypeReference.Definition == dateTimeType)
{
var value = Visit(nodeIn.Source);
if (value is DateTimeOffset)
{
return Instant.FromDateTimeOffset((DateTimeOffset)value);
}
return InstantPattern.General.Parse(Visit(nodeIn.Source).ToString()).Value;
}
return base.Visit(nodeIn);
}
public override object Visit(ConstantNode nodeIn) public override object Visit(ConstantNode nodeIn)
{ {
return nodeIn.Value; return nodeIn.Value;

21
src/Squidex.Read.MongoDb/Contents/Visitors/FilterVisitor.cs

@ -15,6 +15,7 @@ using MongoDB.Bson;
using MongoDB.Driver; using MongoDB.Driver;
using Squidex.Core.Schemas; using Squidex.Core.Schemas;
// ReSharper disable InvertIf
// ReSharper disable SwitchStatementMissingSomeCases // ReSharper disable SwitchStatementMissingSomeCases
// ReSharper disable ConvertIfStatementToSwitchStatement // ReSharper disable ConvertIfStatementToSwitchStatement
@ -49,17 +50,26 @@ namespace Squidex.Read.MongoDb.Contents.Visitors
public override FilterDefinition<MongoContentEntity> Visit(SingleValueFunctionCallNode nodeIn) public override FilterDefinition<MongoContentEntity> Visit(SingleValueFunctionCallNode nodeIn)
{ {
var fieldNode = nodeIn.Parameters.ElementAt(0);
var valueNode = nodeIn.Parameters.ElementAt(1);
if (nodeIn.Name == "endswith") if (nodeIn.Name == "endswith")
{ {
return Filter.Regex(BuildFieldDefinition(nodeIn.Parameters.ElementAt(0)), new BsonRegularExpression(BuildValue(nodeIn.Parameters.ElementAt(1)) + "$", "i")); var value = BuildRegex(valueNode, v => v + "$");
return Filter.Regex(BuildFieldDefinition(fieldNode), value);
} }
if (nodeIn.Name == "startswith") if (nodeIn.Name == "startswith")
{ {
return Filter.Regex(BuildFieldDefinition(nodeIn.Parameters.ElementAt(0)), new BsonRegularExpression("^" + BuildValue(nodeIn.Parameters.ElementAt(1)), "i")); var value = BuildRegex(valueNode, v => "^" + v);
return Filter.Regex(BuildFieldDefinition(fieldNode), value);
} }
if (nodeIn.Name == "contains") if (nodeIn.Name == "contains")
{ {
return Filter.Regex(BuildFieldDefinition(nodeIn.Parameters.ElementAt(0)), new BsonRegularExpression(BuildValue(nodeIn.Parameters.ElementAt(1)).ToString(), "i")); var value = BuildRegex(valueNode, v => v);
return Filter.Regex(BuildFieldDefinition(fieldNode), value);
} }
throw new NotSupportedException(); throw new NotSupportedException();
@ -103,6 +113,11 @@ namespace Squidex.Read.MongoDb.Contents.Visitors
throw new NotSupportedException(); throw new NotSupportedException();
} }
private static BsonRegularExpression BuildRegex(QueryNode node, Func<string, string> formatter)
{
return new BsonRegularExpression(formatter(BuildValue(node).ToString()), "i");
}
private FieldDefinition<MongoContentEntity, object> BuildFieldDefinition(QueryNode nodeIn) private FieldDefinition<MongoContentEntity, object> BuildFieldDefinition(QueryNode nodeIn)
{ {
return PropertyVisitor.Visit(nodeIn, schema); return PropertyVisitor.Visit(nodeIn, schema);

4
src/Squidex.Read.MongoDb/Contents/Visitors/SchemaExtensions.cs

@ -32,9 +32,9 @@ namespace Squidex.Read.MongoDb.Contents.Visitors
var entityType = new EdmEntityType("Squidex", schema.Name); var entityType = new EdmEntityType("Squidex", schema.Name);
entityType.AddStructuralProperty("data", new EdmComplexTypeReference(schemaType, false)); entityType.AddStructuralProperty("data", new EdmComplexTypeReference(schemaType, false));
entityType.AddStructuralProperty("created", EdmPrimitiveTypeKind.Date); entityType.AddStructuralProperty("created", EdmPrimitiveTypeKind.DateTimeOffset);
entityType.AddStructuralProperty("createdBy", EdmPrimitiveTypeKind.String); entityType.AddStructuralProperty("createdBy", EdmPrimitiveTypeKind.String);
entityType.AddStructuralProperty("lastModified", EdmPrimitiveTypeKind.Date); entityType.AddStructuralProperty("lastModified", EdmPrimitiveTypeKind.DateTimeOffset);
entityType.AddStructuralProperty("lastModifiedBy", EdmPrimitiveTypeKind.String); entityType.AddStructuralProperty("lastModifiedBy", EdmPrimitiveTypeKind.String);
model.AddElement(container); model.AddElement(container);

49
tests/Squidex.Read.Tests/MongoDb/Contents/ODataQueryTests.cs

@ -14,6 +14,7 @@ using MongoDB.Driver;
using Moq; using Moq;
using Squidex.Core.Schemas; using Squidex.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.MongoDb;
using Squidex.Read.MongoDb.Contents.Visitors; using Squidex.Read.MongoDb.Contents.Visitors;
using Xunit; using Xunit;
@ -28,11 +29,13 @@ namespace Squidex.Read.MongoDb.Contents
.AddOrUpdateField(new StringField(1, "firstName", .AddOrUpdateField(new StringField(1, "firstName",
new StringFieldProperties { Label = "FirstName", IsLocalizable = true, IsRequired = true, AllowedValues = new[] { "1", "2" }.ToImmutableList() })) new StringFieldProperties { Label = "FirstName", IsLocalizable = true, IsRequired = true, AllowedValues = new[] { "1", "2" }.ToImmutableList() }))
.AddOrUpdateField(new StringField(2, "lastName", .AddOrUpdateField(new StringField(2, "lastName",
new StringFieldProperties { Hints = "Last Name" })) new StringFieldProperties { Hints = "Last Name", Editor = StringFieldEditor.Input }))
.AddOrUpdateField(new BooleanField(3, "admin", .AddOrUpdateField(new BooleanField(3, "isAdmin",
new BooleanFieldProperties())) new BooleanFieldProperties()))
.AddOrUpdateField(new NumberField(4, "age", .AddOrUpdateField(new NumberField(4, "age",
new NumberFieldProperties { MinValue = 1, MaxValue = 10 })); new NumberFieldProperties { MinValue = 1, MaxValue = 10 }))
.AddOrUpdateField(new DateTimeField(5, "birthday",
new DateTimeFieldProperties()));
private readonly IBsonSerializerRegistry registry = BsonSerializer.SerializerRegistry; private readonly IBsonSerializerRegistry registry = BsonSerializer.SerializerRegistry;
private readonly IBsonSerializer<MongoContentEntity> serializer = BsonSerializer.SerializerRegistry.GetSerializer<MongoContentEntity>(); private readonly IBsonSerializer<MongoContentEntity> serializer = BsonSerializer.SerializerRegistry.GetSerializer<MongoContentEntity>();
@ -42,10 +45,15 @@ namespace Squidex.Read.MongoDb.Contents
Language.DE Language.DE
}; };
static ODataQueryTests()
{
InstantSerializer.Register();
}
[Fact] [Fact]
public void Should_parse_query() public void Should_parse_query()
{ {
var parser = schema.ParseQuery(languages, "$filter=data/FirstName/de eq 'Sebastian'"); var parser = schema.ParseQuery(languages, "$filter=data/firstName/de eq 'Sebastian'");
Assert.NotNull(parser); Assert.NotNull(parser);
} }
@ -95,6 +103,24 @@ namespace Squidex.Read.MongoDb.Contents
Assert.Equal(o, i); Assert.Equal(o, i);
} }
[Fact]
public void Should_create_datetime_equals_query()
{
var i = F("$filter=data/birthday/iv eq 1988-01-19T12:00:00Z");
var o = C("{ 'Data.5.iv' : ISODate(\"1988-01-19T12:00:00Z\") }");
Assert.Equal(o, i);
}
[Fact]
public void Should_create_boolean_equals_query()
{
var i = F("$filter=data/isAdmin/iv eq true");
var o = C("{ 'Data.3.iv' : true }");
Assert.Equal(o, i);
}
[Fact] [Fact]
public void Should_create_string_not_equals_query() public void Should_create_string_not_equals_query()
{ {
@ -206,14 +232,25 @@ namespace Squidex.Read.MongoDb.Contents
} }
[Fact] [Fact]
public void Should_not_set_top() public void Should_set_max_top_if_larger()
{
var parser = schema.ParseQuery(languages, "$top=300");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser);
cursor.Verify(x => x.Limit(200));
}
[Fact]
public void Should_set_default_top()
{ {
var parser = schema.ParseQuery(languages, ""); var parser = schema.ParseQuery(languages, "");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser); cursor.Object.Take(parser);
cursor.Verify(x => x.Limit(It.IsAny<int>()), Times.Never); cursor.Verify(x => x.Limit(20));
} }
[Fact] [Fact]

Loading…
Cancel
Save