Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/XrmMockup365/Internal/EntityMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ private static bool Matches(object attr, ConditionOperator op, IEnumerable<objec
return DateTimeCompareNow(attr, op, values);

case ConditionOperator.In:
if (values != null && attr is OptionSetValueCollection optionSetValueCollection)
{
return string.Join(",", values.OrderBy(_ => _)) == string.Join(",", optionSetValueCollection.ToList().Select(_ => _.Value).OrderBy(_ => _));
}
return values.Contains(ValueConverter.ConvertTo(attr, values.FirstOrDefault()?.GetType()));

case ConditionOperator.NotIn:
Expand Down
123 changes: 123 additions & 0 deletions tests/XrmMockup365Test/TestFetchConditionOperators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,136 @@
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace DG.XrmMockupTest
{
public class TestFetchConditionOperators : UnitTestBase
{
public TestFetchConditionOperators(XrmMockupFixture fixture) : base(fixture)
{
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item3 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.checkmark });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item3 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
CreateAccount(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });

void CreateAccount(List<Account_dg_Multiselect> list)
{
for (int i = 0; i < 2; i++)
{
list.Reverse();
var account = new Account();
account.dg_Multiselect = list;
account.Id = orgAdminUIService.Create(account);
}
}
}

private class MultiselectCases : TheoryData<List<Account_dg_Multiselect>>
{
public MultiselectCases()
{
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item3 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item3 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
Add(new List<Account_dg_Multiselect> { Account_dg_Multiselect.Item1, Account_dg_Multiselect.Item2, Account_dg_Multiselect.Item3, Account_dg_Multiselect.Item4 });
}
}

[Theory]
[ClassData(typeof(MultiselectCases))]
public void TestMultiselectConditionOperatorIn(List<Account_dg_Multiselect> optionSetValueCollection)
{
using (var context = new Xrm(orgAdminUIService))
{
var optionSetValues = optionSetValueCollection.Select(_ => (int)_).ToList();
for (int i = 0; i < 2; i++)
{
optionSetValues.Reverse();
string values = string.Empty;
foreach (var value in optionSetValues)
{
values += $"<value>{value}</value>";
}

var fetchXml =
$@"<fetch mapping='logical' version='1.0'>
<entity name='account'>
<filter>
<condition attribute='dg_multiselect' operator='in'>
{values}
</condition>
</filter>
</entity>
</fetch>";
EntityCollection result = Fetch(fetchXml);
Assert.Equal(2, result.Entities.Count);
}
}
}

[Theory]
[ClassData(typeof(MultiselectCases))]
public void TestMultiselectConditionOperatorNotIn(List<Account_dg_Multiselect> optionSetValueCollection)
{
using (var context = new Xrm(orgAdminUIService))
{
var fetchXmlCount =
$@"<fetch mapping='logical' version='1.0'>
<entity name='account'>
<attribute name='name' />
</entity>
</fetch>";
var count = Fetch(fetchXmlCount).Entities.Count;
var optionSetValues = optionSetValueCollection.Select(_ => (int)_).ToList();
for (int i = 0; i < 2; i++)
{
optionSetValues.Reverse();
string values = string.Empty;
foreach (var value in optionSetValues)
{
values += $"<value>{value}</value>";
}

var fetchXml =
$@"<fetch mapping='logical' version='1.0'>
<entity name='account'>
<filter>
<condition attribute='dg_multiselect' operator='not-in'>
{values}
</condition>
</filter>
</entity>
</fetch>";
EntityCollection result = Fetch(fetchXml);
Assert.Equal(count - 2, result.Entities.Count);
}
}
}

[Theory]
Expand Down
42 changes: 26 additions & 16 deletions tests/XrmMockup365Test/TestFormulaFields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,36 @@ public async TTask CanEvaluateExpressionWithRelatedEntity()
[ClassData(typeof(FunctionCases))]
public async TTask CanEvaluateFunction(string formula, object expected)
{
var evaluator = new FormulaFieldEvaluator(serviceFactory);
var result = await evaluator.Evaluate(formula, new Account(), TimeSpan.Zero);

if (result is ErrorValue error && expected is string errorString)
{
var errorMessage = string.Join("\n", error.Errors.Select(e => e.Message));
Assert.Contains(errorString, errorMessage);
}
else if (result is DateTime resultDateTime)
var targetCulture = new CultureInfo("en-US");
var originalUICulture = CultureInfo.CurrentUICulture;
try
{
var expectedDateTime = (expected is DateTime dt)
? dt
: (expected is "DateTime.Now")
? DateTime.Now
: throw new InvalidOperationException("Expected value is not a DateTime or 'DateTime.Now'");
CultureInfo.CurrentUICulture = targetCulture;
var evaluator = new FormulaFieldEvaluator(serviceFactory);
var result = await evaluator.Evaluate(formula, new Account(), TimeSpan.Zero);

if (result is ErrorValue error && expected is string errorString)
{
var errorMessage = string.Join("\n", error.Errors.Select(e => e.Message));
Assert.Contains(errorString, errorMessage);
}
else if (result is DateTime resultDateTime)
{
var expectedDateTime = (expected is DateTime dt)
? dt
: (expected is "DateTime.Now")
? DateTime.Now
: throw new InvalidOperationException("Expected value is not a DateTime or 'DateTime.Now'");
Assert.Equal(expectedDateTime, resultDateTime, TimeSpan.FromSeconds(1));
}
else
{
Assert.Equal(expected, result);
}
}
else
finally
{
Assert.Equal(expected, result);
CultureInfo.CurrentUICulture = originalUICulture;
}
}

Expand Down