Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit e2c5bfe

Browse files
committed
https://github.com/IharYakimush/comminity-data-odata-linq/issues/41
1 parent 5233569 commit e2c5bfe

File tree

11 files changed

+217
-65
lines changed

11 files changed

+217
-65
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using Community.OData.Linq.xTests.SampleData;
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
using Xunit;
10+
using Xunit.Abstractions;
11+
12+
namespace Community.OData.Linq.xTests
13+
{
14+
public class DateTimeFilterTests
15+
{
16+
private readonly ITestOutputHelper output;
17+
private static readonly DateTime dtUtc = new DateTime(2018, 1, 26, 0, 0, 0, DateTimeKind.Utc);
18+
private static readonly DateTime dtLocal = new DateTime(2018, 1, 26, 0, 0, 0, DateTimeKind.Local);
19+
private static readonly DateTime dt = new DateTime(2018, 1, 26, 0, 0, 0);
20+
private static readonly DateTimeOffset dto = new DateTimeOffset(dt, TimeZoneInfo.Local.BaseUtcOffset);
21+
//private readonly DateTimeOffset dtoUtc = new DateTimeOffset(new DateTime(2018, 1, 26).ToUniversalTime());
22+
23+
public DateTimeFilterTests(ITestOutputHelper output)
24+
{
25+
this.output = output ?? throw new ArgumentNullException(nameof(output));
26+
}
27+
28+
[Fact]
29+
public void LocalDateTimeEqualCorrectUtcOffset()
30+
{
31+
string value = dto.ToString("u").Replace(" ", "T");
32+
string filter = $"DateTime eq {value}";
33+
output.WriteLine(filter);
34+
35+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
36+
Assert.Single(result);
37+
output.WriteLine(result.Single().DateTime.ToString());
38+
}
39+
40+
[Fact]
41+
public void LocalDateTimeEqualCorrectLocalOffset()
42+
{
43+
string value = dto.ToString("s") + dto.ToString("zzz");
44+
string filter = $"DateTime eq {value}";
45+
output.WriteLine(filter);
46+
47+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
48+
Assert.Single(result);
49+
output.WriteLine(result.Single().DateTime.ToString());
50+
}
51+
52+
[Fact]
53+
public void LocalDateTimetNotEquaIncorrectUtcOffset()
54+
{
55+
string value = dto.ToString("s") + "Z";
56+
string filter = $"DateTime eq {value}";
57+
output.WriteLine(filter);
58+
59+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
60+
Assert.Empty(result);
61+
}
62+
63+
[Fact]
64+
public void DateTimeOffsetEqualCorrectUtcOffset()
65+
{
66+
string value = dto.ToString("u").Replace(" ", "T");
67+
string filter = $"DateTimeOffset eq {value}";
68+
output.WriteLine(filter);
69+
70+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
71+
Assert.Single(result);
72+
output.WriteLine(result.Single().DateTimeOffset.ToString());
73+
74+
}
75+
76+
[Fact]
77+
public void DateTimeOffsetEqualCorrectLocalOffset()
78+
{
79+
string value = dto.ToString("s") + dto.ToString("zzz");
80+
string filter = $"DateTimeOffset eq {value}";
81+
output.WriteLine(filter);
82+
83+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
84+
Assert.Single(result);
85+
output.WriteLine(result.Single().DateTimeOffset.ToString());
86+
}
87+
88+
[Fact]
89+
public void DateTimeOffsetNotEqualIncorrectUtcOffset()
90+
{
91+
string value = dto.ToString("s") + "Z";
92+
string filter = $"DateTimeOffset eq {value}";
93+
output.WriteLine(filter);
94+
95+
var result = SimpleClass.CreateQuery().OData().Filter(filter).ToArray();
96+
Assert.Empty(result);
97+
}
98+
99+
[Fact]
100+
public void UtcDateTimeEqualCorrectUtcOffset()
101+
{
102+
string value = dto.ToString("s") + "Z";
103+
//string value = dto.ToString("u").Replace(" ", "T");
104+
string filter = $"DateTime eq {value}";
105+
output.WriteLine(filter);
106+
107+
var result = SimpleClass.CreateQuery().OData(c=>c.QuerySettings.DefaultTimeZone = TimeZoneInfo.Utc).Filter(filter).ToArray();
108+
Assert.Single(result);
109+
output.WriteLine(result.Single().DateTime.ToString() + "UTC");
110+
111+
}
112+
113+
[Fact]
114+
public void UtcDateTimeEqualCorrectLocalOffset()
115+
{
116+
string value = dto.DateTime.ToLocalTime().ToString("s").Replace(" ", "T") + dto.ToString("zzz");
117+
string filter = $"DateTime eq {value}";
118+
output.WriteLine(filter);
119+
120+
var result = SimpleClass.CreateQuery().OData(c => c.QuerySettings.DefaultTimeZone = TimeZoneInfo.Utc).Filter(filter).ToArray();
121+
Assert.Single(result);
122+
output.WriteLine(result.Single().DateTime.ToString() + "UTC");
123+
}
124+
125+
[Fact]
126+
public void UtcDateTimeNotEqualIncorrectLocalOffset()
127+
{
128+
string value = dto.ToString("u").Replace(" ", "T").Replace("Z", dto.ToString("zzz"));
129+
string filter = $"DateTime eq {value}";
130+
output.WriteLine(filter);
131+
132+
var result = SimpleClass.CreateQuery().OData(c => c.QuerySettings.DefaultTimeZone = TimeZoneInfo.Utc).Filter(filter).ToArray();
133+
Assert.Empty(result);
134+
}
135+
136+
[Fact]
137+
public void UtcDateTimeNotEqualIncorrectLocalOffset2()
138+
{
139+
string value = dto.ToString("s") + dto.ToString("zzz");
140+
string filter = $"DateTime eq {value}";
141+
output.WriteLine(filter);
142+
143+
var result = SimpleClass.CreateQuery().OData(c => c.QuerySettings.DefaultTimeZone = TimeZoneInfo.Utc).Filter(filter).ToArray();
144+
Assert.Empty(result);
145+
}
146+
147+
[Fact]
148+
public void UtcDateTimetNotEqualIncorrectUtcOffset()
149+
{
150+
string value = dto.ToString("u").Replace(" ", "T");
151+
string filter = $"DateTime eq {value}";
152+
output.WriteLine(filter);
153+
154+
var result = SimpleClass.CreateQuery().OData(c => c.QuerySettings.DefaultTimeZone = TimeZoneInfo.Utc).Filter(filter).ToArray();
155+
Assert.Empty(result);
156+
}
157+
158+
[Fact]
159+
public void DateTimeCompare()
160+
{
161+
// Compare method compares the Ticks property of t1 and t2 but ignores their Kind property.
162+
// Before comparing DateTime objects, ensure that the objects represent times in the same time zone.
163+
Assert.Equal(dt, dtLocal);
164+
Assert.Equal(dt, dtUtc);
165+
Assert.Equal(dtUtc, dtLocal);
166+
}
167+
}
168+
}

Community.Data.OData.Linq.xTests/ExpandTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void ExpandLink()
4141
// Not expanded by default
4242
Assert.Equal(3, metadata.Count);
4343

44-
Assert.Equal(6, (metadata["Link1"] as ISelectExpandWrapper).ToDictionary().Count);
44+
Assert.Equal(7, (metadata["Link1"] as ISelectExpandWrapper).ToDictionary().Count);
4545
}
4646

4747
[Fact]
@@ -53,7 +53,7 @@ public void ExpandSelect()
5353

5454
// Not expanded by default
5555
Assert.Equal(2, metadata.Count);
56-
Assert.Equal(6, (metadata["Link1"] as ISelectExpandWrapper).ToDictionary().Count);
56+
Assert.Equal(7, (metadata["Link1"] as ISelectExpandWrapper).ToDictionary().Count);
5757
}
5858

5959
[Fact]
@@ -155,8 +155,8 @@ public void ExpandWithAttributes()
155155
// Not expanded by default
156156
Assert.Equal(4, metadata.Count);
157157

158-
Assert.Equal(6, (metadata["AutoExpandLink"] as ISelectExpandWrapper).ToDictionary().Count);
159-
Assert.Equal(6, (metadata["AutoExpandAndSelectLink"] as ISelectExpandWrapper).ToDictionary().Count);
158+
Assert.Equal(7, (metadata["AutoExpandLink"] as ISelectExpandWrapper).ToDictionary().Count);
159+
Assert.Equal(7, (metadata["AutoExpandAndSelectLink"] as ISelectExpandWrapper).ToDictionary().Count);
160160
}
161161

162162
[Fact]
@@ -169,7 +169,7 @@ public void ExpandWithAttributesAndExplicit()
169169
// Not expanded by default
170170
Assert.Equal(3, metadata.Count);
171171

172-
Assert.Equal(6, (metadata["AutoExpandAndSelectLink"] as ISelectExpandWrapper).ToDictionary().Count);
172+
Assert.Equal(7, (metadata["AutoExpandAndSelectLink"] as ISelectExpandWrapper).ToDictionary().Count);
173173
}
174174

175175
[Fact]

Community.Data.OData.Linq.xTests/FilterTests.cs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
namespace Community.OData.Linq.xTests
22
{
3-
using System.ComponentModel;
43
using System.Linq;
54

65
using Community.OData.Linq.xTests.SampleData;
@@ -10,7 +9,7 @@
109
using Xunit;
1110

1211
public class FilterTests
13-
{
12+
{
1413
[Fact]
1514
public void WhereById()
1615
{
@@ -51,16 +50,7 @@ public void WhereByRandomStringThrowException()
5150
Assert.Throws<ODataException>(
5251
() => SimpleClass.CreateQuery().OData().Filter("qwe"));
5352
}
54-
55-
[Fact]
56-
public void WhereByDateTime()
57-
{
58-
var result = SimpleClass.CreateQuery().OData().Filter("DateTime gt 2010-01-25T02:13:40.00Z").ToArray();
59-
60-
Assert.Single(result);
61-
Assert.Equal("n1", result[0].Name);
62-
}
63-
53+
6454
[Fact]
6555
public void WhereByEnumString()
6656
{
@@ -126,6 +116,6 @@ public void WhereByIgnoreDataMemberThrowException()
126116
{
127117
Assert.Throws<ODataException>(
128118
() => SimpleClass.CreateQuery().OData(s => s.EnableCaseInsensitive = false).Filter($"{nameof(SimpleClass.NameToIgnore)} eq 'ni1'"));
129-
}
119+
}
130120
}
131121
}

Community.Data.OData.Linq.xTests/Issues/Issue32.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,13 @@ public void Expand()
8787
// to replicate please use the following cases
8888
//string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq false;$expand=URLT($Select=*;$filter=isDeleted eq false))"; // Case 1 - Expand Filter working fine (Aparently)
8989
string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq false;$expand=URLT($Select=*;$Filter=isDeleted eq true))"; // Case 2 - Expand Filter not working
90-
// string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq true;$expand=URLT($Select=*;$filter=isDeleted eq true))"; // Case 3 - Expand Filter not working fine
91-
// string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq true;$expand=URLT($Select=*;$filter=URLTN eq 'a'))"; // Case 4 - Expand Filter not working fine on diferent DataTypes
90+
// string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq true;$expand=URLT($Select=*;$filter=isDeleted eq true))"; // Case 3 - Expand Filter not working fine
91+
// string ExpandStr = "DA($select=DAID,isDeleted;$Filter=isDeleted eq true;$expand=URLT($Select=*;$filter=URLTN eq 'a'))"; // Case 4 - Expand Filter not working fine on diferent DataTypes
9292

93-
IQueryable<PDA> query = items.AsQueryable();
93+
ODataQuery<PDA> query = items.AsQueryable().OData();
94+
95+
ODataSettings settings = (ODataSettings)query.ServiceProvider.GetService(typeof(ODataSettings));
96+
Assert.True(settings.EnableCaseInsensitive);
9497

9598
var result = query.OData().Filter(filter).OrderBy(orderBy).SelectExpand(selectStr, ExpandStr).ToJson(settings => settings.NullValueHandling = NullValueHandling.Ignore);
9699
string str = result.ToString();

Community.Data.OData.Linq.xTests/SampleData/SimpleClass.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,22 @@ public class SimpleClass
1111
{
1212
private static readonly SimpleClass[] items =
1313
{
14-
new SimpleClass {Id = 1, Name = "n1", DateTime = new DateTime(2018, 1, 26), TestEnum = TestEnum.Item1, NameToIgnore = "ni1", NameNotFilter="nf1"},
15-
new SimpleClass {Id = 2, Name = "n2", DateTime = new DateTime(2001, 1, 26), TestEnum = TestEnum.Item2, NameToIgnore = "ni1", NameNotFilter="nf2"}
14+
new SimpleClass {
15+
Id = 1,
16+
Name = "n1",
17+
DateTimeOffset = new DateTimeOffset(new DateTime(2018, 1, 26), TimeZoneInfo.Local.BaseUtcOffset),
18+
DateTime = new DateTime(2018, 1, 26),
19+
TestEnum = TestEnum.Item1,
20+
NameToIgnore = "ni1",
21+
NameNotFilter="nf1"},
22+
new SimpleClass {
23+
Id = 2,
24+
Name = "n2",
25+
DateTimeOffset = new DateTimeOffset(new DateTime(2001, 1, 26), TimeZoneInfo.Local.BaseUtcOffset),
26+
DateTime = new DateTime(2001, 1, 26),
27+
TestEnum = TestEnum.Item2,
28+
NameToIgnore = "ni1",
29+
NameNotFilter="nf2"}
1630
};
1731

1832
public static IQueryable<SimpleClass> CreateQuery()
@@ -26,6 +40,8 @@ public static IQueryable<SimpleClass> CreateQuery()
2640

2741
public DateTime DateTime { get; set; }
2842

43+
public DateTimeOffset DateTimeOffset { get; set; }
44+
2945
public TestEnum TestEnum { get; set; }
3046

3147
[IgnoreDataMember]

Community.Data.OData.Linq.xTests/SelectTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public void SelectDefault()
2020

2121
IDictionary<string, object> metadata = result[0].ToDictionary();
2222

23-
Assert.Equal(6, metadata.Count);
23+
Assert.Equal(7, metadata.Count);
2424
}
2525

2626
[Fact]
@@ -30,7 +30,7 @@ public void SelectAllt()
3030

3131
IDictionary<string, object> metadata = result[0].ToDictionary();
3232

33-
Assert.Equal(6, metadata.Count);
33+
Assert.Equal(7, metadata.Count);
3434
}
3535

3636
[Fact]

Community.Data.OData.Linq/OData/Formatter/EdmPrimitiveHelpers.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Community.OData.Linq.OData.Formatter
1616

1717
internal static class EdmPrimitiveHelpers
1818
{
19-
public static object ConvertPrimitiveValue(object value, Type type)
19+
public static object ConvertPrimitiveValue(object value, Type type, TimeZoneInfo timeZone)
2020
{
2121
Contract.Assert(value != null);
2222
Contract.Assert(type != null);
@@ -81,8 +81,7 @@ public static object ConvertPrimitiveValue(object value, Type type)
8181
{
8282
if (value is DateTimeOffset)
8383
{
84-
DateTimeOffset dateTimeOffsetValue = (DateTimeOffset)value;
85-
TimeZoneInfo timeZone = TimeZoneInfoHelper.TimeZone;
84+
DateTimeOffset dateTimeOffsetValue = (DateTimeOffset)value;
8685
dateTimeOffsetValue = TimeZoneInfo.ConvertTime(dateTimeOffsetValue, timeZone);
8786
return dateTimeOffsetValue.DateTime;
8887
}

Community.Data.OData.Linq/OData/Query/Expressions/ExpressionBinderBase.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,11 @@ internal Expression CreateBinaryExpression(BinaryOperatorKind binaryOperator, Ex
116116

117117
if (leftUnderlyingType == typeof(DateTime) && rightUnderlyingType == typeof(DateTimeOffset))
118118
{
119-
right = DateTimeOffsetToDateTime(right);
119+
right = DateTimeOffsetToDateTime(right, this.QuerySettings.DefaultTimeZone);
120120
}
121121
else if (rightUnderlyingType == typeof(DateTime) && leftUnderlyingType == typeof(DateTimeOffset))
122122
{
123-
left = DateTimeOffsetToDateTime(left);
123+
left = DateTimeOffsetToDateTime(left, this.QuerySettings.DefaultTimeZone);
124124
}
125125

126126
if ((IsDateOrOffset(leftUnderlyingType) && IsDate(rightUnderlyingType)) ||
@@ -856,7 +856,7 @@ internal static object ExtractParameterizedConstant(Expression expression)
856856
return null;
857857
}
858858

859-
internal static Expression DateTimeOffsetToDateTime(Expression expression)
859+
internal static Expression DateTimeOffsetToDateTime(Expression expression, TimeZoneInfo timeZone)
860860
{
861861
var unaryExpression = expression as UnaryExpression;
862862
if (unaryExpression != null)
@@ -871,7 +871,7 @@ internal static Expression DateTimeOffsetToDateTime(Expression expression)
871871
var dto = parameterizedConstantValue as DateTimeOffset?;
872872
if (dto != null)
873873
{
874-
expression = Expression.Constant(EdmPrimitiveHelpers.ConvertPrimitiveValue(dto.Value, typeof(DateTime)));
874+
expression = Expression.Constant(EdmPrimitiveHelpers.ConvertPrimitiveValue(dto.Value, typeof(DateTime), timeZone));
875875
}
876876
return expression;
877877
}

0 commit comments

Comments
 (0)