CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
ValidationTests.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="ValidationTests.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>no summary</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Linq;
10using System.Collections.Generic;
11using System.ComponentModel;
12using System.Text;
13using Csla.Core;
14using Csla.Rules;
15using UnitDriven;
17using System.Threading.Tasks;
18using Csla.TestHelpers;
19
20#if NUNIT
21using NUnit.Framework;
22using TestClass = NUnit.Framework.TestFixtureAttribute;
23using TestInitialize = NUnit.Framework.SetUpAttribute;
24using TestCleanup = NUnit.Framework.TearDownAttribute;
25using TestMethod = NUnit.Framework.TestAttribute;
26#elif MSTEST
27using Microsoft.VisualStudio.TestTools.UnitTesting;
28#endif
29
31{
32 [TestClass()]
34 {
35
36 private static TestDIContext _testDIContext;
37
39 public static void ClassInitialize(TestContext context)
40 {
41 _testDIContext = TestDIContextFactory.CreateDefaultContext();
42 }
43
44 [TestMethod()]
46 {
47 //works now because we are calling ValidationRules.CheckRules() in DataPortal_Create
48 UnitTestContext context = GetContext();
50 var root = await CreateHasRulesManagerAsync();
51 context.Assert.AreEqual("<new>", root.Name);
52 context.Assert.AreEqual(true, root.IsValid, "should be valid on create");
53 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
54
55 root.BeginEdit();
56 root.Name = "";
57 root.CancelEdit();
58
59 context.Assert.AreEqual("<new>", root.Name);
60 context.Assert.AreEqual(true, root.IsValid, "should be valid after CancelEdit");
61 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
62
63 root.BeginEdit();
64 root.Name = "";
65 root.ApplyEdit();
66
67 context.Assert.AreEqual("", root.Name);
68 context.Assert.AreEqual(false, root.IsValid);
69 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
70 context.Assert.AreEqual("Name required", root.BrokenRulesCollection[0].Description);
71 context.Assert.Success();
72
73 context.Complete();
74 }
75
76 [TestMethod()]
78 {
79 //should work since ValidationRules.CheckRules() is called in DataPortal_Create
81 var root = await CreateHasRulesManager2Async("<new>");
82 Assert.AreEqual("<new>", root.Name);
83 Assert.AreEqual(true, root.IsValid, "should be valid on create");
84 Assert.AreEqual(0, root.BrokenRulesCollection.Count);
85
86 root.BeginEdit();
87 root.Name = "";
88 root.CancelEdit();
89
90 Assert.AreEqual("<new>", root.Name);
91 Assert.AreEqual(true, root.IsValid, "should be valid after CancelEdit");
92 Assert.AreEqual(0, root.BrokenRulesCollection.Count);
93
94 root.BeginEdit();
95 root.Name = "";
96 root.ApplyEdit();
97
98 Assert.AreEqual("", root.Name);
99 Assert.AreEqual(false, root.IsValid);
100 Assert.AreEqual(1, root.BrokenRulesCollection.Count);
101 Assert.AreEqual("Name required", root.BrokenRulesCollection[0].Description);
102 Assert.AreEqual("Name required", root.BrokenRulesCollection.GetFirstMessage(HasRulesManager2.NameProperty).Description);
103 Assert.AreEqual("Name required", root.BrokenRulesCollection.GetFirstBrokenRule(HasRulesManager2.NameProperty).Description);
104 }
105
106 [TestMethod()]
108 {
109 //should work since ValidationRules.CheckRules() is called in DataPortal_Create
111 UnitTestContext context = GetContext();
112 var root = await CreateHasRulesManagerAsync();
113 context.Assert.AreEqual("<new>", root.Name);
114 context.Assert.AreEqual(true, root.IsValid, "should be valid on create");
115 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
116
117 bool validationComplete = false;
118 root.ValidationComplete += (vo, ve) => { validationComplete = true; };
119
120 root.BeginEdit();
121 root.Name = "";
122 context.Assert.AreEqual("", root.Name);
123 context.Assert.AreEqual(false, root.IsValid);
124 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
125 context.Assert.AreEqual("Name required", root.BrokenRulesCollection[0].Description);
126 context.Assert.IsTrue(validationComplete, "ValidationComplete should have run");
127 root.BeginEdit();
128 root.Name = "Begin 1";
129 context.Assert.AreEqual("Begin 1", root.Name);
130 context.Assert.AreEqual(true, root.IsValid);
131 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
132 root.BeginEdit();
133 root.Name = "Begin 2";
134 context.Assert.AreEqual("Begin 2", root.Name);
135 context.Assert.AreEqual(true, root.IsValid);
136 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
137 root.BeginEdit();
138 root.Name = "Begin 3";
139 context.Assert.AreEqual("Begin 3", root.Name);
140 context.Assert.AreEqual(true, root.IsValid);
141 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
142
143 HasRulesManager hrmClone = root.Clone();
144
145 //Test validation rule cancels for both clone and cloned
146 root.CancelEdit();
147 context.Assert.AreEqual("Begin 2", root.Name);
148 context.Assert.AreEqual(true, root.IsValid);
149 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
150 hrmClone.CancelEdit();
151 context.Assert.AreEqual("Begin 2", hrmClone.Name);
152 context.Assert.AreEqual(true, hrmClone.IsValid);
153 context.Assert.AreEqual(0, hrmClone.BrokenRulesCollection.Count);
154 root.CancelEdit();
155 context.Assert.AreEqual("Begin 1", root.Name);
156 context.Assert.AreEqual(true, root.IsValid);
157 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
158 hrmClone.CancelEdit();
159 context.Assert.AreEqual("Begin 1", hrmClone.Name);
160 context.Assert.AreEqual(true, hrmClone.IsValid);
161 context.Assert.AreEqual(0, hrmClone.BrokenRulesCollection.Count);
162 root.CancelEdit();
163 context.Assert.AreEqual("", root.Name);
164 context.Assert.AreEqual(false, root.IsValid);
165 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
166 context.Assert.AreEqual("Name required", root.BrokenRulesCollection[0].Description);
167 hrmClone.CancelEdit();
168 context.Assert.AreEqual("", hrmClone.Name);
169 context.Assert.AreEqual(false, hrmClone.IsValid);
170 context.Assert.AreEqual(1, hrmClone.BrokenRulesCollection.Count);
171 context.Assert.AreEqual("Name required", hrmClone.BrokenRulesCollection[0].Description);
172 root.CancelEdit();
173 context.Assert.AreEqual("<new>", root.Name);
174 context.Assert.AreEqual(true, root.IsValid);
175 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
176 hrmClone.CancelEdit();
177 context.Assert.AreEqual("<new>", hrmClone.Name);
178 context.Assert.AreEqual(true, hrmClone.IsValid);
179 context.Assert.AreEqual(0, hrmClone.BrokenRulesCollection.Count);
180 context.Assert.Success();
181
182 context.Complete();
183 }
184
185 [TestMethod()]
187 {
188 //this test uses HasRulesManager2, which assigns criteria._name to its public
189 //property in DataPortal_Create. If it used HasRulesManager, it would fail
190 //the first assert, but pass the others
192 var root = await CreateHasRulesManager2Async("test");
193 Assert.AreEqual(true, root.IsValid);
194 root.BeginEdit();
195 root.Name = "";
196 root.ApplyEdit();
197
198 Assert.AreEqual(false, root.IsValid);
199 HasRulesManager2 rootClone = root.Clone();
200 Assert.AreEqual(false, rootClone.IsValid);
201
202 rootClone.Name = "something";
203 Assert.AreEqual(true, rootClone.IsValid);
204 }
205
206 [TestMethod()]
207
208 public async Task BreakRequiredRule()
209 {
211 var root = await CreateHasRulesManagerAsync();
212 root.Name = "";
213 Assert.AreEqual(false, root.IsValid, "should not be valid");
214 Assert.AreEqual(1, root.BrokenRulesCollection.Count);
215 Assert.AreEqual("Name required", root.BrokenRulesCollection[0].Description);
216 }
217
218 [TestMethod()]
219
220 public async Task BreakLengthRule()
221 {
223 UnitTestContext context = GetContext();
224 var root = await CreateHasRulesManagerAsync();
225 root.Name = "12345678901";
226 context.Assert.AreEqual(false, root.IsValid, "should not be valid");
227 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
228 //Assert.AreEqual("Name too long", root.GetBrokenRulesCollection[0].Description);
229 Assert.AreEqual("Name can not exceed 10 characters", root.BrokenRulesCollection[0].Description);
230
231 root.Name = "1234567890";
232 context.Assert.AreEqual(true, root.IsValid, "should be valid");
233 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
234 context.Assert.Success();
235 context.Complete();
236 }
237
238 [TestMethod()]
239
240 public async Task BreakLengthRuleAndClone()
241 {
243 UnitTestContext context = GetContext();
244 var root = await CreateHasRulesManagerAsync();
245 root.Name = "12345678901";
246 context.Assert.AreEqual(false, root.IsValid, "should not be valid before clone");
247 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
248 //Assert.AreEqual("Name too long", root.GetBrokenRulesCollection[0].Description;
249 Assert.AreEqual("Name can not exceed 10 characters", root.BrokenRulesCollection[0].Description);
250
251 root = (HasRulesManager)(root.Clone());
252 context.Assert.AreEqual(false, root.IsValid, "should not be valid after clone");
253 context.Assert.AreEqual(1, root.BrokenRulesCollection.Count);
254 //Assert.AreEqual("Name too long", root.GetBrokenRulesCollection[0].Description;
255 context.Assert.AreEqual("Name can not exceed 10 characters", root.BrokenRulesCollection[0].Description);
256
257 root.Name = "1234567890";
258 context.Assert.AreEqual(true, root.IsValid, "Should be valid");
259 context.Assert.AreEqual(0, root.BrokenRulesCollection.Count);
260 context.Assert.Success();
261 context.Complete();
262 }
263
264 [TestMethod()]
265 public void RegExSSN()
266 {
268 UnitTestContext context = GetContext();
269
270 HasRegEx root = CreateWithoutCriteria<HasRegEx>();
271
272 root.Ssn = "555-55-5555";
273 root.Ssn2 = "555-55-5555";
274 context.Assert.IsTrue(root.IsValid, "Ssn should be valid");
275
276 root.Ssn = "555-55-5555d";
277 context.Assert.IsFalse(root.IsValid, "Ssn should not be valid");
278
279 root.Ssn = "555-55-5555";
280 root.Ssn2 = "555-55-5555d";
281 context.Assert.IsFalse(root.IsValid, "Ssn should not be valid");
282
283 context.Assert.Success();
284 context.Complete();
285 }
286
287 [TestMethod]
288 public void MergeBrokenRules()
289 {
290 UnitTestContext context = GetContext();
291 var root = CreateWithoutCriteria<BrokenRulesMergeRoot>();
292 root.Validate();
294 context.Assert.AreEqual(2, list.Count, "Should have 2 broken rules");
295 context.Assert.AreEqual("rule://csla.test.validationrules.brokenrulesmergeroot-rulebroken/Test1", list[0].RuleName);
296
297 context.Assert.Success();
298 context.Complete();
299 }
300
301 [TestMethod]
303 {
305 using (UnitTestContext context = GetContext())
306 {
307 var root = await CreateHasRulesManager2Async();
308 string expected = root.Name;
309 root.BeginEdit();
310 root.Name = "";
311 HasRulesManager2 rootClone = root.Clone();
312 rootClone.CancelEdit();
313
314 string actual = rootClone.Name;
315 context.Assert.AreEqual(expected, actual);
316 context.Assert.Try(rootClone.ApplyEdit);
317
318 context.Assert.Success();
319 context.Complete();
320 }
321 }
322
323 [TestMethod()]
324 public async Task ListChangedEventTrigger()
325 {
327 UnitTestContext context = GetContext();
328 var root = await CreateWithoutCriteriaAsync<HasChildren>();
329 context.Assert.AreEqual(false, root.IsValid);
330 root.BeginEdit();
331 root.ChildList.Add(CreateChildWithoutCriteria<Child>());
332 context.Assert.AreEqual(true, root.IsValid);
333
334 root.CancelEdit();
335 context.Assert.AreEqual(false, root.IsValid);
336
337 context.Assert.Success();
338 context.Complete();
339 }
340
341 [TestMethod]
343 {
344 UnitTestContext context = GetContext();
345 var root = CreateWithoutCriteria<HasBadRule>();
346 root.Validate();
347 context.Assert.IsFalse(root.IsValid);
348 context.Assert.AreEqual(1, root.GetBrokenRules().Count);
349#if WINDOWS_PHONE
350 context.Assert.AreEqual("rule://csla.test.validationrules.hasbadrule-badrule/null:InvalidOperationException", root.GetBrokenRules()[0].Description);
351#else
352 context.Assert.AreEqual("rule://csla.test.validationrules.hasbadrule-badrule/(object):Operation is not valid due to the current state of the object.", root.GetBrokenRules()[0].Description);
353#endif
354 context.Assert.Success();
355 context.Complete();
356 }
357
358 [TestMethod]
359 public void PrivateField()
360 {
361 UnitTestContext context = GetContext();
362 var root = CreateWithoutCriteria<HasPrivateFields>();
363 root.Validate();
364 context.Assert.IsFalse(root.IsValid);
365 root.Name = "abc";
366 context.Assert.IsTrue(root.IsValid);
367 context.Assert.Success();
368 context.Complete();
369 }
370
371 [TestMethod]
372 public void MinMaxValue()
373 {
374 var context = GetContext();
375 var root = CreateWithoutCriteria<UsesCommonRules>();
376 context.Assert.AreEqual(1, root.Data);
377
378 context.Assert.IsFalse(root.IsValid);
379 context.Assert.IsTrue(root.BrokenRulesCollection[0].Description.Length > 0);
380
381
382 root.Data = 0;
383 context.Assert.IsFalse(root.IsValid);
384
385 root.Data = 20;
386 context.Assert.IsFalse(root.IsValid);
387
388 root.Data = 15;
389 context.Assert.IsTrue(root.IsValid);
390
391 context.Assert.Success();
392 context.Complete();
393 }
394
395 [TestMethod]
397 {
398 var context = GetContext();
399 var root = CreateWithoutCriteria<MinMaxNullableRules>();
400 context.Assert.IsNull(root.DataNullable);
401
402 context.Assert.IsFalse(root.IsValid);
403 context.Assert.IsTrue(root.BrokenRulesCollection[0].Description.Length > 0);
404
405
406 root.DataNullable = 0;
407 context.Assert.IsFalse(root.IsValid);
408
409 root.DataNullable = 20;
410 context.Assert.IsFalse(root.IsValid);
411
412 root.DataNullable = 15;
413 context.Assert.IsTrue(root.IsValid);
414
415 context.Assert.Success();
416 context.Complete();
417 }
418
419 [TestMethod]
420 public void MinMaxLength()
421 {
422 var context = GetContext();
423
424 var root = CreateWithoutCriteria<UsesCommonRules>();
425 root.Data = 15;
426 context.Assert.IsTrue(root.IsValid, "Should start valid");
427
428 root.MinCheck = "a";
429 context.Assert.IsFalse(root.IsValid, "Min too short");
430
431 root.MinCheck = "123456";
432 context.Assert.IsTrue(root.IsValid, "Min OK");
433
434 root.MaxCheck = "a";
435 context.Assert.IsTrue(root.IsValid, "Max OK");
436
437 root.MaxCheck = "123456";
438 context.Assert.IsFalse(root.IsValid, "Max too long");
439
440 context.Assert.Success();
441 context.Complete();
442 }
443
444 [TestMethod]
445 public void TwoRules()
446 {
447 var context = GetContext();
448
449 var root = new TwoPropertyRules();
451
452 var applicationContext = _testDIContext.CreateTestApplicationContext();
453 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
454 new Dictionary<Core.IPropertyInfo, object> {
457 });
458 ((Csla.Rules.IBusinessRule)rule).Execute(ctx);
459 context.Assert.AreEqual(0, ctx.Results.Count);
460
461 ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
462 new Dictionary<Core.IPropertyInfo, object> {
465 });
466 ((Csla.Rules.IBusinessRule)rule).Execute(ctx);
467 context.Assert.AreEqual(1, ctx.Results.Count);
468
469 context.Assert.Success();
470 context.Complete();
471 }
472
473 [TestMethod]
475 {
476 var context = GetContext();
477
478 context.Assert.Try(() =>
479 {
480 var root = new HasLazyField();
481 root.CheckRules();
482
483 string broken;
484
485 var rootEI = (IDataErrorInfo)root;
486 broken = rootEI[HasLazyField.Value1Property.Name];
487
488 context.Assert.AreEqual("PrimaryProperty does not exist.", broken);
489 var value = root.Value1; // intializes field
490
491 root.CheckRules();
492 broken = rootEI[HasLazyField.Value1Property.Name];
493 context.Assert.AreEqual("PrimaryProperty has value.", broken);
494
495 context.Assert.Success();
496 });
497
498 context.Complete();
499
500 }
501
502 [TestMethod]
504 {
505 IDataPortal<DirtyAfterOutValueChangesProperty> dataPortal = _testDIContext.CreateDataPortal<DirtyAfterOutValueChangesProperty>();
506
507 var context = GetContext();
508
509 var root = dataPortal.Fetch();
510 context.Assert.IsFalse(root.IsDirty);
511 context.Assert.AreEqual("csla rocks", root.Value1);
512 root.CheckRules();
513 context.Assert.IsTrue(root.IsDirty);
514 context.Assert.AreEqual("CSLA ROCKS", root.Value1);
515 context.Assert.Success();
516 context.Complete();
517 }
518
519 [TestMethod]
521 {
522 IDataPortal<DirtyAfterOutValueChangesProperty> dataPortal = _testDIContext.CreateDataPortal<DirtyAfterOutValueChangesProperty>();
523
524 var context = GetContext();
525
526 var root = dataPortal.Fetch("CSLA ROCKS");
527 context.Assert.IsFalse(root.IsDirty);
528 context.Assert.AreEqual("CSLA ROCKS", root.Value1);
529 root.CheckRules();
530 context.Assert.IsFalse(root.IsDirty);
531 context.Assert.AreEqual("CSLA ROCKS", root.Value1);
532 context.Assert.Success();
533 context.Complete();
534 }
535
536 private T CreateWithoutCriteria<T>()
537 {
538 IDataPortal<T> dataPortal = _testDIContext.CreateDataPortal<T>();
539
540 return dataPortal.Create();
541 }
542
543 private async Task<T> CreateWithoutCriteriaAsync<T>()
544 {
545 IDataPortal<T> dataPortal = _testDIContext.CreateDataPortal<T>();
546
547 return await dataPortal.CreateAsync();
548 }
549
550 private T CreateChildWithoutCriteria<T>()
551 {
552 IChildDataPortal<T> dataPortal = _testDIContext.CreateChildDataPortal<T>();
553
554 return dataPortal.CreateChild();
555 }
556
557 private async Task<HasRulesManager> CreateHasRulesManagerAsync()
558 {
559 IDataPortal<HasRulesManager> dataPortal = _testDIContext.CreateDataPortal<HasRulesManager>();
560
561 return await dataPortal.CreateAsync(new HasRulesManager.Criteria());
562 }
563
564 private async Task<HasRulesManager2> CreateHasRulesManager2Async()
565 {
566 IDataPortal<HasRulesManager2> dataPortal = _testDIContext.CreateDataPortal<HasRulesManager2>();
567
568 return await dataPortal.CreateAsync();
569 }
570
571 private async Task<HasRulesManager2> CreateHasRulesManager2Async(string ident)
572 {
573 IDataPortal<HasRulesManager2> dataPortal = _testDIContext.CreateDataPortal<HasRulesManager2>();
574
575 return await dataPortal.CreateAsync(new HasRulesManager2.Criteria(ident));
576 }
577
578 }
579
581 public class HasBadRule : BusinessBase<HasBadRule>
582 {
583 public static PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
584 public int Id
585 {
586 get { return GetProperty(IdProperty); }
587 set { SetProperty(IdProperty, value); }
588 }
589
590 public void Validate()
591 {
593 }
594
595 public new Rules.BrokenRulesCollection GetBrokenRules()
596 {
598 }
599
600 protected override void AddBusinessRules()
601 {
602 base.AddBusinessRules();
603 BusinessRules.AddRule(new BadRule());
604 }
605
606 private class BadRule : Rules.BusinessRule
607 {
608 protected override void Execute(Rules.IRuleContext context)
609 {
610 throw new InvalidOperationException();
611 }
612 }
613
614 [Create]
615 private void Create()
616 {
617 }
618 }
619
621 public class HasPrivateFields : BusinessBase<HasPrivateFields>
622 {
623 public static PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name), RelationshipTypes.PrivateField);
624 private string _name = NameProperty.DefaultValue;
625 public string Name
626 {
627 get { return GetProperty(NameProperty, _name); }
628 set { SetProperty(NameProperty, ref _name, value); }
629 }
630
631 public void Validate()
632 {
634 }
635
636 protected override object ReadProperty(Core.IPropertyInfo propertyInfo)
637 {
638 if (ReferenceEquals(propertyInfo, NameProperty))
639 return _name;
640 else
641 return base.ReadProperty(propertyInfo);
642 }
643
644 protected override void AddBusinessRules()
645 {
646 base.AddBusinessRules();
648 }
649
650 [Create]
651 private void Create()
652 {
653 }
654 }
655
657 public class UsesCommonRules : BusinessBase<UsesCommonRules>
658 {
659 private static PropertyInfo<int> DataProperty = RegisterProperty<int>(c => c.Data, null, 1);
660 public int Data
661 {
662 get { return GetProperty(DataProperty); }
663 set { SetProperty(DataProperty, value); }
664 }
665
666 private static PropertyInfo<string> MinCheckProperty = RegisterProperty<string>(c => c.MinCheck, null, "123456");
667 public string MinCheck
668 {
669 get { return GetProperty(MinCheckProperty); }
670 set { SetProperty(MinCheckProperty, value); }
671 }
672
673 private static PropertyInfo<string> MaxCheckProperty = RegisterProperty<string>(c => c.MaxCheck);
674 public string MaxCheck
675 {
676 get { return GetProperty(MaxCheckProperty); }
677 set { SetProperty(MaxCheckProperty, value); }
678 }
679
680 protected override void AddBusinessRules()
681 {
682 base.AddBusinessRules();
683 BusinessRules.AddRule(new Csla.Rules.CommonRules.MinValue<int>(DataProperty, 5));
684 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxValue<int>(DataProperty, 15));
685
686 BusinessRules.AddRule(new Csla.Rules.CommonRules.MinLength(MinCheckProperty, 5));
687 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(MaxCheckProperty, 5));
688 }
689
690 [Create]
691 private void Create()
692 {
694 }
695 }
696
698 public class MinMaxNullableRules : BusinessBase<MinMaxNullableRules>
699 {
700 private static PropertyInfo<int?> DataNullableProperty = RegisterProperty<int?>(c => c.DataNullable);
701 public int? DataNullable
702 {
703 get { return GetProperty(DataNullableProperty); }
704 set { SetProperty(DataNullableProperty, value); }
705 }
706
707 protected override void AddBusinessRules()
708 {
709 base.AddBusinessRules();
710
711 BusinessRules.AddRule(new Csla.Rules.CommonRules.MinValue<int>(DataNullableProperty, 5));
712 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxValue<int>(DataNullableProperty, 15));
713 }
714
715 [Create]
716 private void Create()
717 {
719 }
720 }
721
723 public class TwoPropertyRules : BusinessBase<TwoPropertyRules>
724 {
725 public static PropertyInfo<string> Value1Property = RegisterProperty<string>(c => c.Value1);
726 public string Value1
727 {
728 get { return GetProperty(Value1Property); }
729 set { SetProperty(Value1Property, value); }
730 }
731
732 public static PropertyInfo<string> Value2Property = RegisterProperty<string>(c => c.Value2);
733 public string Value2
734 {
735 get { return GetProperty(Value2Property); }
736 set { SetProperty(Value2Property, value); }
737 }
738
739 protected override void AddBusinessRules()
740 {
741 base.AddBusinessRules();
744 }
745 }
746
747 public class TwoProps : Csla.Rules.BusinessRule
748 {
750 public TwoProps(Csla.Core.IPropertyInfo primaryProperty, Csla.Core.IPropertyInfo secondProperty)
751 : base(primaryProperty)
752 {
753 SecondaryProperty = secondProperty;
755 InputProperties = new List<Core.IPropertyInfo> { PrimaryProperty, SecondaryProperty };
756 }
757
758 protected override void Execute(Rules.IRuleContext context)
759 {
760 var v1 = (string)context.InputPropertyValues[PrimaryProperty];
761 var v2 = (string)context.InputPropertyValues[SecondaryProperty];
762 if (string.IsNullOrEmpty(v1) || string.IsNullOrEmpty(v2))
763 context.AddErrorResult(string.Format("v1:{0}, v2:{1}", v1, v2));
764 }
765 }
766
768 public class HasLazyField : BusinessBase<HasLazyField>
769 {
770 public static PropertyInfo<string> Value1Property = RegisterProperty<string>(nameof(Value1), RelationshipTypes.LazyLoad);
771 public string Value1
772 {
773 get
774 {
775 return LazyGetProperty(Value1Property, () => string.Empty);
776 //if (!FieldManager.FieldExists(Value1Property))
777 // SetProperty(Value1Property, string.Empty);
778 //return GetProperty(Value1Property);
779 }
780 set { SetProperty(Value1Property, value); }
781 }
782
783 protected override void AddBusinessRules()
784 {
785 base.AddBusinessRules();
787 }
788
789 public void CheckRules()
790 {
792 }
793 }
794
796 public class DirtyAfterOutValueChangesProperty : BusinessBase<DirtyAfterOutValueChangesProperty>
797 {
798 public static PropertyInfo<string> Value1Property = RegisterProperty<string>(c => c.Value1);
799 public string Value1
800 {
801 get { return GetProperty(Value1Property); }
802 set { SetProperty(Value1Property, value); }
803 }
804
806 { }
807
808 protected override void AddBusinessRules()
809 {
810 base.AddBusinessRules();
812 }
813
814 private class ToUpper : Csla.Rules.BusinessRule
815 {
816 public ToUpper(IPropertyInfo primaryProperty)
817 : base(primaryProperty)
818 {
819 InputProperties = new List<IPropertyInfo>(){primaryProperty};
820 }
821
822 protected override void Execute(IRuleContext context)
823 {
824 var value = (string) context.InputPropertyValues[PrimaryProperty];
825 context.AddOutValue(PrimaryProperty, value.ToUpperInvariant());
826 }
827 }
828
829 public void CheckRules()
830 {
832 }
833
834 [Fetch]
835 private void Fetch()
836 {
837 Fetch("csla rocks");
838 }
839
840 [Fetch]
841 private void Fetch(string value)
842 {
843 using (BypassPropertyChecks)
844 {
845 Value1 = value;
846 }
847 }
848 }
849
850
852 {
854 : base(primaryProperty)
855 {
856 InputProperties = new List<Core.IPropertyInfo> { primaryProperty };
857 }
858
859 protected override void Execute(Rules.IRuleContext context)
860 {
861 if (context.InputPropertyValues.ContainsKey(PrimaryProperty))
862 {
863 context.AddErrorResult("PrimaryProperty has value.");
864 }
865 else
866 {
867 context.AddErrorResult("PrimaryProperty does not exist.");
868 }
869
870
871 }
872 }
873
874
875 [TestClass]
876 public class RuleContextTests
877 {
878 private static TestDIContext _testDIContext;
879
881 public static void ClassInitialize(TestContext context)
882 {
883 _testDIContext = TestDIContextFactory.CreateDefaultContext();
884 }
885
886 [TestMethod]
887 [ExpectedException(typeof(ArgumentException))]
889 {
890 var root = new TwoPropertyRules();
892
893 var applicationContext = _testDIContext.CreateTestApplicationContext();
894 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
895 new Dictionary<Core.IPropertyInfo, object>
896 {
899 });
900 ctx.AddErrorResult(string.Empty, false);
901 Assert.Fail("Must throw exception.");
902 }
903
904 [TestMethod]
905 [ExpectedException(typeof(ArgumentException))]
907 {
908 var root = new TwoPropertyRules();
910
911 var applicationContext = _testDIContext.CreateTestApplicationContext();
912 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
913 new Dictionary<Core.IPropertyInfo, object>
914 {
917 });
919 Assert.Fail("Must throw exception.");
920 }
921
922 [TestMethod]
923 [ExpectedException(typeof(ArgumentException))]
925 {
926 var root = new TwoPropertyRules();
928
929 var applicationContext = _testDIContext.CreateTestApplicationContext();
930 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
931 new Dictionary<Core.IPropertyInfo, object>
932 {
935 });
936 ctx.AddWarningResult(string.Empty, false);
937 Assert.Fail("Must throw exception.");
938 }
939
940 [TestMethod]
941 [ExpectedException(typeof(ArgumentException))]
943 {
944 var root = new TwoPropertyRules();
946
947 var applicationContext = _testDIContext.CreateTestApplicationContext();
948 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
949 new Dictionary<Core.IPropertyInfo, object>
950 {
953 });
955 Assert.Fail("Must throw exception.");
956 }
957
958 [TestMethod]
959 [ExpectedException(typeof(ArgumentException))]
961 {
962 var root = new TwoPropertyRules();
964
965 var applicationContext = _testDIContext.CreateTestApplicationContext();
966 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
967 new Dictionary<Core.IPropertyInfo, object>
968 {
971 });
972 ctx.AddInformationResult(string.Empty, false);
973 Assert.Fail("Must throw exception.");
974 }
975
976 [TestMethod]
977 [ExpectedException(typeof(ArgumentException))]
979 {
980 var root = new TwoPropertyRules();
982
983 var applicationContext = _testDIContext.CreateTestApplicationContext();
984 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
985 new Dictionary<Core.IPropertyInfo, object>
986 {
989 });
991 Assert.Fail("Must throw exception.");
992 }
993
994
995 [TestMethod]
997 {
998 var root = new TwoPropertyRules();
1000
1001 var applicationContext = _testDIContext.CreateTestApplicationContext();
1002 var ctx = new Csla.Rules.RuleContext(applicationContext, null, rule, root,
1003 new Dictionary<Core.IPropertyInfo, object>
1004 {
1007 });
1008 ctx.AddSuccessResult(false);
1009 Assert.IsTrue(true, "Must not fail.");
1010 }
1011
1012 }
1013}
This is the base class from which most business objects will be derived.
Definition: BusinessBase.cs:38
T Clone()
Creates a clone of the object.
Definition: BusinessBase.cs:79
Maintains metadata about a property.
A collection of currently broken rules.
BrokenRulesCollection()
Creates a read-write instance of the collection.
virtual Csla.Core.IPropertyInfo PrimaryProperty
Gets or sets the primary property affected by this rule.
List< Csla.Core.IPropertyInfo > InputProperties
Gets a list of secondary property values to be supplied to the rule when it is executed.
List< Csla.Core.IPropertyInfo > AffectedProperties
Gets a list of properties affected by this rule.
Base class used to create business and validation rules.
Definition: BusinessRule.cs:15
Tracks the business rules for a business object.
List< string > CheckRules()
Invokes all rules for the business type.
void AddRule(IBusinessRuleBase rule)
Associates a business rule with the business object.
BrokenRulesCollection GetBrokenRules()
Gets the broken rules list.
Business rule for a maximum length string.
Definition: CommonRules.cs:168
Business rule for a maximum value.
Definition: CommonRules.cs:399
Business rule for a minimum length string.
Definition: CommonRules.cs:239
Business rule for a minimum value.
Definition: CommonRules.cs:311
Business rule for a required string.
Definition: CommonRules.cs:106
Context information provided to a business rule when it is invoked.
Definition: RuleContext.cs:51
void AddWarningResult(string description)
Add a Warning severity result to the Results list.
Definition: RuleContext.cs:320
void AddSuccessResult(bool stopProcessing)
Add a Success severity result to the Results list.
Definition: RuleContext.cs:390
void AddErrorResult(string description)
Add a Error severity result to the Results list.
Definition: RuleContext.cs:283
void Complete()
Indicates that the rule processing is complete, so CSLA .NET will process the Results list.
Definition: RuleContext.cs:436
void AddInformationResult(string description)
Add an Information severity result to the Results list.
Definition: RuleContext.cs:357
Static dictionary-like class that offers similar functionality to GlobalContext This is used in tests...
Definition: TestResults.cs:21
static void Reinitialise()
Reinitialise the dictionary, clearing any existing results, ready for the next test
Definition: TestResults.cs:69
CheckLazyInputFieldExists(Csla.Core.IPropertyInfo primaryProperty)
override void Execute(Rules.IRuleContext context)
static PropertyInfo< int > IdProperty
new Rules.BrokenRulesCollection GetBrokenRules()
static PropertyInfo< string > Value1Property
static PropertyInfo< string > NameProperty
override object ReadProperty(Core.IPropertyInfo propertyInfo)
static PropertyInfo< string > NameProperty
static void ClassInitialize(TestContext context)
static PropertyInfo< string > Value1Property
static PropertyInfo< string > Value2Property
Csla.Core.IPropertyInfo SecondaryProperty
TwoProps(Csla.Core.IPropertyInfo primaryProperty, Csla.Core.IPropertyInfo secondProperty)
override void Execute(Rules.IRuleContext context)
static void ClassInitialize(TestContext context)
Type to carry context information for DI in unit tests
void IsFalse(bool condition)
Definition: Asserter.cs:40
void Try(Action p)
Definition: Asserter.cs:60
void IsTrue(bool condition)
Definition: Asserter.cs:30
UnitTestContext GetContext()
Definition: TestBase.cs:12
Maintains metadata about a property.
Interface defining the members of the child data portal type.
object CreateChild(params object[] criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...
Interface defining the members of the data portal type.
Definition: IDataPortalT.cs:17
Task< object > CreateAsync(params object[] criteria)
Starts an asynchronous data portal operation to create a business object.
object Fetch(params object[] criteria)
Called by a factory method in a business class to retrieve an object, which is loaded with values fro...
object Create(params object[] criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...
Interface defining a business/validation rule implementation.
Context information provided to a business rule when it is invoked.
Definition: IRuleContext.cs:22
void AddOutValue(object value)
Add an outbound value to update the rule's primary property on the business object once the rule is c...
Dictionary< Csla.Core.IPropertyInfo, object > InputPropertyValues
Gets a dictionary containing copies of property values from the target business object.
Definition: IRuleContext.cs:37
RelationshipTypes
List of valid relationship types between a parent object and another object through a managed propert...
@ Serializable
Prevents updating or inserting until the transaction is complete.
@ Execute
Execute operation.