public void CreateRule_GivenInvalidRuleName_ThrowsInvalidRuleException() { // Arrange dynamic content = new ExpandoObject(); content.Prop1 = 123; content.Prop2 = "Sample string"; content.Prop3 = 500.34m; RuleDataModel <ContentType, ConditionType> ruleDataModel = new RuleDataModel <ContentType, ConditionType> { Content = content, ContentType = ContentType.ContentTypeSample, DateBegin = new DateTime(2020, 1, 1), DateEnd = null, Name = null, Priority = 1, RootCondition = null }; RuleFactory <ContentType, ConditionType> ruleFactory = new RuleFactory <ContentType, ConditionType>(); // Act InvalidRuleException invalidRuleException = Assert.Throws <InvalidRuleException>(() => ruleFactory.CreateRule(ruleDataModel)); // Assert invalidRuleException.Should().NotBeNull(); invalidRuleException.Errors.Should().NotBeEmpty(); invalidRuleException.Errors.Should().Contain("'Name' must not be empty."); }
/// <summary> /// 解析普通文本文档 /// </summary> /// <param name="fs"></param> /// <param name="encoding"></param> /// <returns></returns> private static RuleDataModel CreatFromTextFile(Stream fs, Encoding encoding) { List <string> lines = new List <string>(); fs.Position = 0L; using (StreamReader streamReader = new StreamReader(fs, encoding)) { while (streamReader.Peek() >= 0) { string str = streamReader.ReadLine(); if (!string.IsNullOrEmpty(str)) { lines.Add(str); } } } RuleDataModel data = new RuleDataModel() { OriginalFilePath = "", FileHander = lines[0], FgLarge = LineDataModel.CreatFromLineString(lines[1]) }; for (int i = 2; i < lines.Count; i++) { data.TextData.Add(LineDataModel.CreatFromLineString(lines[i])); } fs.Close(); return(data); }
public async Task AddRuleAsync_GivenRule_ConvertsToRuleDataModelAndAddsToDataSource() { // Arrange Rule <ContentType, ConditionType> rule = new Rule <ContentType, ConditionType>(); RuleDataModel <ContentType, ConditionType> ruleDataModel = new RuleDataModel <ContentType, ConditionType>(); IInMemoryRulesStorage <ContentType, ConditionType> inMemoryRulesStorage = Mock.Of <IInMemoryRulesStorage <ContentType, ConditionType> >(); IRuleFactory <ContentType, ConditionType> ruleFactory = Mock.Of <IRuleFactory <ContentType, ConditionType> >(); Mock.Get(ruleFactory) .Setup(x => x.CreateRule(rule)) .Returns(ruleDataModel) .Verifiable(); Mock.Get(inMemoryRulesStorage) .Setup(x => x.AddRule(ruleDataModel)) .Verifiable(); InMemoryProviderRulesDataSource <ContentType, ConditionType> inMemoryProviderRulesDataSource = new InMemoryProviderRulesDataSource <ContentType, ConditionType>(inMemoryRulesStorage, ruleFactory); // Act await inMemoryProviderRulesDataSource.AddRuleAsync(rule).ConfigureAwait(false); // Assert Mock.VerifyAll(Mock.Get(inMemoryRulesStorage), Mock.Get(ruleFactory)); }
/// <summary> /// Adds a new rule to data source. /// </summary> /// <param name="rule">The rule.</param> public async Task AddRuleAsync(Rule <TContentType, TConditionType> rule) { IMongoCollection <RuleDataModel> rulesCollection = this.mongoDatabase.GetCollection <RuleDataModel>(this.mongoDbProviderSettings.RulesCollectionName); RuleDataModel ruleDataModel = this.ruleFactory.CreateRule(rule); await rulesCollection.InsertOneAsync(ruleDataModel).ConfigureAwait(false); }
public Rule <TContentType, TConditionType> CreateRule(RuleDataModel <TContentType, TConditionType> ruleDataModel) { if (ruleDataModel is null) { throw new ArgumentNullException(nameof(ruleDataModel)); } ContentContainer <TContentType> contentContainer = new ContentContainer <TContentType>(ruleDataModel.ContentType, (t) => (object)ruleDataModel.Content); RuleBuilderResult <TContentType, TConditionType> ruleBuilderResult = RuleBuilder.NewRule <TContentType, TConditionType>() .WithName(ruleDataModel.Name) .WithDatesInterval(ruleDataModel.DateBegin, ruleDataModel.DateEnd) .WithCondition(cnb => ruleDataModel.RootCondition is { } ? this.ConvertConditionNode(cnb, ruleDataModel.RootCondition) : null)
/// <summary> /// Adds a new rule to data source. /// </summary> /// <param name="rule">The rule.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">rule</exception> public Task AddRuleAsync(Rule <TContentType, TConditionType> rule) { if (rule is null) { throw new ArgumentNullException(nameof(rule)); } return(Task.Run(() => { RuleDataModel <TContentType, TConditionType> ruleDataModel = this.ruleFactory.CreateRule(rule); this.inMemoryRulesStorage.AddRule(ruleDataModel); })); }
public void AddRule(RuleDataModel <TContentType, TConditionType> ruleDataModel) { List <RuleDataModel <TContentType, TConditionType> > contentTypeRules = GetRulesCollectionByContentType(ruleDataModel.ContentType); lock (contentTypeRules) { if (contentTypeRules.Any(r => string.Equals(r.Name, ruleDataModel.Name))) { throw new InvalidOperationException($"Rule with name '{ruleDataModel.Name}' already exists."); } contentTypeRules.Add(ruleDataModel); } }
/// <summary> /// 解析JSON文件 /// </summary> /// <param name="file"></param> /// <returns></returns> private static RuleDataModel CreatFromJsonFile(string file) { LineDataModel[] array = JsonConvert.DeserializeObject <LineDataModel[]>(File.ReadAllText(file).Replace("\t", "")); RuleDataModel data = new RuleDataModel(); data.OriginalFilePath = file; data.FileHander = string.Empty; data.FgLarge = array[0]; for (int i = 1; i < array.Length; i++) { data.TextData.Add(array[i]); } return(data); }
public void CreateRule_GivenNullRuleDataModel_ThrowsArgumentNullException() { // Arrange RuleDataModel <ContentType, ConditionType> ruleDataModel = null; RuleFactory <ContentType, ConditionType> ruleFactory = new RuleFactory <ContentType, ConditionType>(); // Act ArgumentNullException argumentNullException = Assert.Throws <ArgumentNullException>(() => ruleFactory.CreateRule(ruleDataModel)); // Assert argumentNullException.Should().NotBeNull(); argumentNullException.ParamName.Should().Be(nameof(ruleDataModel)); }
public void UpdateRule(RuleDataModel <TContentType, TConditionType> ruleDataModel) { List <RuleDataModel <TContentType, TConditionType> > contentTypeRules = GetRulesCollectionByContentType(ruleDataModel.ContentType); lock (contentTypeRules) { RuleDataModel <TContentType, TConditionType> existent = contentTypeRules.FirstOrDefault(r => string.Equals(r.Name, ruleDataModel.Name)); if (existent is null) { throw new InvalidOperationException($"Rule with name '{ruleDataModel.Name}' does not exist, no update can be done."); } contentTypeRules.Remove(existent); contentTypeRules.Add(ruleDataModel); } }
/// <summary> /// 解析被ZLIB压缩的文本内容 /// </summary> /// <param name="fs"></param> /// <param name="br"></param> /// <returns></returns> private static RuleDataModel CreatFromeZlibFile(FileStream fs, BinaryReader br) { List <string> lines = new List <string>(); var dataLength = br.ReadInt32(); fs.Position = fs.Length - dataLength; int b1 = br.ReadByte(); int b2 = br.ReadByte(); if ((0x78 != b1 && 0x58 != b1) || 0 != (b1 << 8 | b2) % 31) { throw new InvalidDataException("Data not recoginzed as zlib-compressed stream"); } using (var deStream = new DeflateStream(new MemoryStream(br.ReadBytes(dataLength - 2)), CompressionMode.Decompress, true)) { using (var sr = new StreamReader(deStream, Encoding.Unicode)) { while (sr.Peek() >= 0) { string str = sr.ReadLine(); if (!string.IsNullOrEmpty(str)) { lines.Add(str); } } } } RuleDataModel data = new RuleDataModel() { OriginalFilePath = fs.Name, FileHander = lines[0], FgLarge = LineDataModel.CreatFromLineString(lines[1]) }; for (int i = 2; i < lines.Count; i++) { data.TextData.Add(LineDataModel.CreatFromLineString(lines[i])); } br.Close(); fs.Close(); return(data); }
public ValueApiModel CreateRule() { RuleDataModel data = new RuleDataModel { Conditions = new List <ConditionModel>(), Actions = new List <IActionModel>(), Enabled = true, Deleted = false, TimePeriod = 60000, // a value from timePeriodMap, a field of the RuleReferenceDatModel Name = this.rand.NextString(), Description = this.rand.NextString(), GroupId = this.rand.NextString(), Severity = this.rand.NextString(), Calculation = this.rand.NextString(), }; return(new ValueApiModel { Key = this.rand.NextString(), ETag = this.rand.NextString(), Data = JsonConvert.SerializeObject(data), }); }
/// <summary> /// Updates the existent rule on data source. /// </summary> /// <param name="rule">The rule.</param> public async Task UpdateRuleAsync(Rule <TContentType, TConditionType> rule) { IMongoCollection <RuleDataModel> rulesCollection = this.mongoDatabase.GetCollection <RuleDataModel>(this.mongoDbProviderSettings.RulesCollectionName); RuleDataModel ruleDataModel = this.ruleFactory.CreateRule(rule); FilterDefinition <RuleDataModel> filterDefinition = Builders <RuleDataModel> .Filter.Eq(x => x.Name, ruleDataModel.Name); FieldDefinition <RuleDataModel, object> contentField = "Content"; IEnumerable <UpdateDefinition <RuleDataModel> > updateDefinitions = new UpdateDefinition <RuleDataModel>[] { Builders <RuleDataModel> .Update.Set(contentField, (object)ruleDataModel.Content), Builders <RuleDataModel> .Update.Set(r => r.ContentType, ruleDataModel.ContentType), Builders <RuleDataModel> .Update.Set(r => r.DateBegin, ruleDataModel.DateBegin), Builders <RuleDataModel> .Update.Set(r => r.DateEnd, ruleDataModel.DateEnd), Builders <RuleDataModel> .Update.Set(r => r.Name, ruleDataModel.Name), Builders <RuleDataModel> .Update.Set(r => r.Priority, ruleDataModel.Priority), Builders <RuleDataModel> .Update.Set(r => r.RootCondition, ruleDataModel.RootCondition), }; UpdateDefinition <RuleDataModel> updateDefinition = Builders <RuleDataModel> .Update.Combine(updateDefinitions); await rulesCollection.UpdateOneAsync(filterDefinition, updateDefinition).ConfigureAwait(false); }
public override async Task <ConversionApiModel> ConvertAsync(string tenantId, string operationId = null) { ValueListApiModel rules = null; try { rules = await this.StorageAdapterClient.GetAllAsync(this.Entity); } catch (Exception e) { this.Logger.LogError(e, "Unable to query {entity} using storage adapter. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId); throw e; } if (rules.Items.Count() == 0 || rules == null) { string errorMessage = $"No entities were receieved from storage adapter to convert to {this.Entity}. OperationId: {operationId}. TenantId: {tenantId}"; this.Logger.LogError(new Exception(errorMessage), errorMessage); throw new ResourceNotFoundException("No entities were receieved from storage adapter to convert to rules."); } List <RuleReferenceDataModel> jsonRulesList = new List <RuleReferenceDataModel>(); try { foreach (ValueApiModel item in rules.Items) { try { RuleDataModel dataModel = JsonConvert.DeserializeObject <RuleDataModel>(item.Data); RuleModel ruleModel = new RuleModel(item.Key, dataModel); // return a RuleReferenceModel which is a conversion from the RuleModel into a SAjob readable format with additional metadata RuleReferenceDataModel referenceModel = new RuleReferenceDataModel(ruleModel); jsonRulesList.Add(referenceModel); } catch (Exception) { this.Logger.LogInformation("Unable to convert a rule to the proper reference data model for {entity}. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId); } } if (jsonRulesList.Count() == 0) { throw new ResourceNotSupportedException("No rules were able to be converted to the proper rule reference data model."); } } catch (Exception e) { this.Logger.LogError(e, "Unable to convert {entity} queried from storage adapter to appropriate data model. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId); throw e; } string fileContent = null; try { fileContent = JsonConvert.SerializeObject(jsonRulesList, Formatting.Indented); } catch (Exception e) { this.Logger.LogError(e, "Unable to serialize the IEnumerable of {entity} data models for the temporary file content. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId); throw e; } string blobFilePath = await this.WriteFileContentToBlobAsync(fileContent, tenantId, operationId); ConversionApiModel conversionResponse = new ConversionApiModel { TenantId = tenantId, BlobFilePath = blobFilePath, Entities = rules, OperationId = operationId, }; this.Logger.LogInformation("Successfully Completed {entity} conversion\n{model}", this.Entity, JsonConvert.SerializeObject(conversionResponse)); return(conversionResponse); }
public void CreateRule_GivenRuleDataModelWithComposedNodeAndChildNodesOfEachDataType_ReturnsRuleInstance() { // Arrange dynamic content = new ExpandoObject(); content.Prop1 = 123; content.Prop2 = "Sample string"; content.Prop3 = 500.34m; ValueConditionNodeDataModel integerConditionNodeDataModel = new ValueConditionNodeDataModel { ConditionType = "SampleIntegerCondition", DataType = DataTypes.Integer, LogicalOperator = LogicalOperators.Eval, Operand = 20, Operator = Operators.GreaterThan }; ValueConditionNodeDataModel stringConditionNodeDataModel = new ValueConditionNodeDataModel { ConditionType = "SampleStringCondition", DataType = DataTypes.String, LogicalOperator = LogicalOperators.Eval, Operand = "TEST", Operator = Operators.Equal }; ValueConditionNodeDataModel decimalConditionNodeDataModel = new ValueConditionNodeDataModel { ConditionType = "SampleDecimalCondition", DataType = DataTypes.Decimal, LogicalOperator = LogicalOperators.Eval, Operand = 50.3m, Operator = Operators.LesserThanOrEqual }; ValueConditionNodeDataModel booleanConditionNodeDataModel = new ValueConditionNodeDataModel { ConditionType = "SampleBooleanCondition", DataType = DataTypes.Boolean, LogicalOperator = LogicalOperators.Eval, Operand = true, Operator = Operators.NotEqual }; RuleDataModel ruleDataModel = new RuleDataModel { Content = content, ContentType = "ContentTypeSample", DateBegin = new System.DateTime(2020, 1, 1), DateEnd = null, Id = ObjectId.GenerateNewId(), Name = "My rule used for testing purposes", Priority = 1, RootCondition = new ComposedConditionNodeDataModel { LogicalOperator = LogicalOperators.And, ChildConditionNodes = new ConditionNodeDataModel[] { integerConditionNodeDataModel, stringConditionNodeDataModel, decimalConditionNodeDataModel, booleanConditionNodeDataModel } } }; IContentSerializationProvider <ContentType> contentSerializationProvider = Mock.Of <IContentSerializationProvider <ContentType> >(); RuleFactory <ContentType, ConditionType> ruleFactory = new RuleFactory <ContentType, ConditionType>(contentSerializationProvider); // Act Rule <ContentType, ConditionType> rule = ruleFactory.CreateRule(ruleDataModel); // Assert rule.Should().NotBeNull(); rule.ContentContainer.Should().NotBeNull() .And.BeOfType <SerializedContentContainer <ContentType> >(); rule.DateBegin.Should().Be(ruleDataModel.DateBegin); rule.DateEnd.Should().BeNull(); rule.Name.Should().Be(ruleDataModel.Name); rule.Priority.Should().Be(ruleDataModel.Priority); rule.RootCondition.Should().BeOfType <ComposedConditionNode <ConditionType> >(); ComposedConditionNode <ConditionType> composedConditionNode = rule.RootCondition.As <ComposedConditionNode <ConditionType> >(); composedConditionNode.LogicalOperator.Should().Be(LogicalOperators.And); composedConditionNode.ChildConditionNodes.Should().HaveCount(4); IEnumerable <IntegerConditionNode <ConditionType> > integerConditionNodes = composedConditionNode.ChildConditionNodes.OfType <IntegerConditionNode <ConditionType> >(); integerConditionNodes.Should().HaveCount(1); IntegerConditionNode <ConditionType> integerConditionNode = integerConditionNodes.First(); integerConditionNode.Should().NotBeNull(); integerConditionNode.ConditionType.Should().Match <ConditionType>(x => x == Enum.Parse <ConditionType>(integerConditionNodeDataModel.ConditionType)); integerConditionNode.DataType.Should().Be(integerConditionNodeDataModel.DataType); integerConditionNode.LogicalOperator.Should().Be(integerConditionNodeDataModel.LogicalOperator); integerConditionNode.Operand.Should().Match(x => object.Equals(x, integerConditionNodeDataModel.Operand)); integerConditionNode.Operator.Should().Be(integerConditionNodeDataModel.Operator); IEnumerable <StringConditionNode <ConditionType> > stringConditionNodes = composedConditionNode.ChildConditionNodes.OfType <StringConditionNode <ConditionType> >(); stringConditionNodes.Should().HaveCount(1); StringConditionNode <ConditionType> stringConditionNode = stringConditionNodes.First(); stringConditionNode.Should().NotBeNull(); stringConditionNode.ConditionType.Should().Match <ConditionType>(x => x == Enum.Parse <ConditionType>(stringConditionNodeDataModel.ConditionType)); stringConditionNode.DataType.Should().Be(stringConditionNodeDataModel.DataType); stringConditionNode.LogicalOperator.Should().Be(stringConditionNodeDataModel.LogicalOperator); stringConditionNode.Operand.Should().Match(x => object.Equals(x, stringConditionNodeDataModel.Operand)); stringConditionNode.Operator.Should().Be(stringConditionNodeDataModel.Operator); IEnumerable <DecimalConditionNode <ConditionType> > decimalConditionNodes = composedConditionNode.ChildConditionNodes.OfType <DecimalConditionNode <ConditionType> >(); decimalConditionNodes.Should().HaveCount(1); DecimalConditionNode <ConditionType> decimalConditionNode = decimalConditionNodes.First(); decimalConditionNode.Should().NotBeNull(); decimalConditionNode.ConditionType.Should().Match <ConditionType>(x => x == Enum.Parse <ConditionType>(decimalConditionNodeDataModel.ConditionType)); decimalConditionNode.DataType.Should().Be(decimalConditionNodeDataModel.DataType); decimalConditionNode.LogicalOperator.Should().Be(decimalConditionNodeDataModel.LogicalOperator); decimalConditionNode.Operand.Should().Match(x => object.Equals(x, decimalConditionNodeDataModel.Operand)); decimalConditionNode.Operator.Should().Be(decimalConditionNodeDataModel.Operator); IEnumerable <BooleanConditionNode <ConditionType> > booleanConditionNodes = composedConditionNode.ChildConditionNodes.OfType <BooleanConditionNode <ConditionType> >(); booleanConditionNodes.Should().HaveCount(1); BooleanConditionNode <ConditionType> booleanConditionNode = booleanConditionNodes.First(); booleanConditionNode.Should().NotBeNull(); booleanConditionNode.ConditionType.Should().Match <ConditionType>(x => x == Enum.Parse <ConditionType>(booleanConditionNodeDataModel.ConditionType)); booleanConditionNode.DataType.Should().Be(booleanConditionNodeDataModel.DataType); booleanConditionNode.LogicalOperator.Should().Be(booleanConditionNodeDataModel.LogicalOperator); booleanConditionNode.Operand.Should().Be(Convert.ToBoolean(booleanConditionNodeDataModel.Operand)); booleanConditionNode.Operator.Should().Be(booleanConditionNodeDataModel.Operator); }
public void CreateRule_GivenRuleWithComposedNodeAndChildNodesOfEachDataType_ReturnsRuleDataModelInstance() { // Arrange dynamic content = new ExpandoObject(); content.Prop1 = 123; content.Prop2 = "Sample string"; content.Prop3 = 500.34m; IContentSerializer contentSerializer = Mock.Of <IContentSerializer>(); Mock.Get(contentSerializer) .Setup(x => x.Deserialize(It.IsAny <object>(), It.IsAny <Type>())) .Returns((object)content); IContentSerializationProvider <ContentType> contentSerializationProvider = Mock.Of <IContentSerializationProvider <ContentType> >(); Mock.Get(contentSerializationProvider) .Setup(x => x.GetContentSerializer(ContentType.ContentTypeSample)) .Returns(contentSerializer); BooleanConditionNode <ConditionType> booleanConditionNode = null; DecimalConditionNode <ConditionType> decimalConditionNode = null; IntegerConditionNode <ConditionType> integerConditionNode = null; StringConditionNode <ConditionType> stringConditionNode = null; Rule <ContentType, ConditionType> rule1 = RuleBuilder.NewRule <ContentType, ConditionType>() .WithName("My rule used for testing purposes") .WithDateBegin(new DateTime(2020, 1, 1)) .WithPriority(1) .WithSerializedContent(ContentType.ContentTypeSample, (object)content, contentSerializationProvider) .WithCondition(cnb => cnb.AsComposed() .WithLogicalOperator(LogicalOperators.And) .AddCondition(cnb1 => booleanConditionNode = cnb1.AsValued(ConditionType.SampleBooleanCondition) .OfDataType <bool>() .WithComparisonOperator(Operators.NotEqual) .SetOperand(true) .Build() as BooleanConditionNode <ConditionType>) .AddCondition(cnb1 => decimalConditionNode = cnb1.AsValued(ConditionType.SampleDecimalCondition) .OfDataType <decimal>() .WithComparisonOperator(Operators.LesserThanOrEqual) .SetOperand(50.3m) .Build() as DecimalConditionNode <ConditionType>) .AddCondition(cnb1 => integerConditionNode = cnb1.AsValued(ConditionType.SampleIntegerCondition) .OfDataType <int>() .WithComparisonOperator(Operators.GreaterThan) .SetOperand(20) .Build() as IntegerConditionNode <ConditionType>) .AddCondition(cnb1 => stringConditionNode = cnb1.AsValued(ConditionType.SampleStringCondition) .OfDataType <string>() .WithComparisonOperator(Operators.Equal) .SetOperand("TEST") .Build() as StringConditionNode <ConditionType>) .Build()) .Build().Rule; RuleFactory <ContentType, ConditionType> ruleFactory = new RuleFactory <ContentType, ConditionType>(contentSerializationProvider); // Act RuleDataModel rule = ruleFactory.CreateRule(rule1); // Assert rule.Should().NotBeNull(); object content1 = rule.Content; content1.Should().NotBeNull() .And.BeSameAs(content); rule.DateBegin.Should().Be(rule.DateBegin); rule.DateEnd.Should().BeNull(); rule.Name.Should().Be(rule.Name); rule.Priority.Should().Be(rule.Priority); rule.RootCondition.Should().BeOfType <ComposedConditionNodeDataModel>(); ComposedConditionNodeDataModel composedConditionNodeDataModel = rule.RootCondition.As <ComposedConditionNodeDataModel>(); composedConditionNodeDataModel.LogicalOperator.Should().Be(LogicalOperators.And); composedConditionNodeDataModel.ChildConditionNodes.Should().HaveCount(4); IEnumerable <ValueConditionNodeDataModel> valueConditionNodeDataModels = composedConditionNodeDataModel.ChildConditionNodes.OfType <ValueConditionNodeDataModel>(); valueConditionNodeDataModels.Should().HaveCount(4); ValueConditionNodeDataModel integerConditionNodeDataModel = valueConditionNodeDataModels.First(v => v.DataType == DataTypes.Integer); integerConditionNodeDataModel.Should().NotBeNull(); integerConditionNodeDataModel.ConditionType.Should().Match <string>(x => integerConditionNode.ConditionType == Enum.Parse <ConditionType>(x)); integerConditionNodeDataModel.DataType.Should().Be(integerConditionNode.DataType); integerConditionNodeDataModel.LogicalOperator.Should().Be(integerConditionNode.LogicalOperator); integerConditionNodeDataModel.Operand.Should().Match(x => object.Equals(x, integerConditionNode.Operand)); integerConditionNodeDataModel.Operator.Should().Be(integerConditionNode.Operator); ValueConditionNodeDataModel stringConditionNodeDataModel = valueConditionNodeDataModels.First(v => v.DataType == DataTypes.String); stringConditionNodeDataModel.Should().NotBeNull(); stringConditionNodeDataModel.ConditionType.Should().Match <string>(x => stringConditionNode.ConditionType == Enum.Parse <ConditionType>(x)); stringConditionNodeDataModel.DataType.Should().Be(stringConditionNode.DataType); stringConditionNodeDataModel.LogicalOperator.Should().Be(stringConditionNode.LogicalOperator); stringConditionNodeDataModel.Operand.Should().Match(x => object.Equals(x, stringConditionNode.Operand)); stringConditionNodeDataModel.Operator.Should().Be(stringConditionNode.Operator); ValueConditionNodeDataModel decimalConditionNodeDataModel = valueConditionNodeDataModels.First(v => v.DataType == DataTypes.Decimal); decimalConditionNodeDataModel.Should().NotBeNull(); decimalConditionNodeDataModel.ConditionType.Should().Match <string>(x => decimalConditionNode.ConditionType == Enum.Parse <ConditionType>(x)); decimalConditionNodeDataModel.DataType.Should().Be(decimalConditionNode.DataType); decimalConditionNodeDataModel.LogicalOperator.Should().Be(decimalConditionNode.LogicalOperator); decimalConditionNodeDataModel.Operand.Should().Match(x => object.Equals(x, decimalConditionNode.Operand)); decimalConditionNodeDataModel.Operator.Should().Be(decimalConditionNode.Operator); ValueConditionNodeDataModel booleanConditionNodeDataModel = valueConditionNodeDataModels.First(v => v.DataType == DataTypes.Boolean); booleanConditionNodeDataModel.Should().NotBeNull(); booleanConditionNodeDataModel.ConditionType.Should().Match <string>(x => booleanConditionNode.ConditionType == Enum.Parse <ConditionType>(x)); booleanConditionNodeDataModel.DataType.Should().Be(booleanConditionNode.DataType); booleanConditionNodeDataModel.LogicalOperator.Should().Be(booleanConditionNode.LogicalOperator); booleanConditionNodeDataModel.Operand.Should().Be(Convert.ToBoolean(booleanConditionNode.Operand)); booleanConditionNodeDataModel.Operator.Should().Be(booleanConditionNode.Operator); }