diff --git a/src/OpenRiaServices.Client/Test/Client.Test/Data/DomainClients/City.partial.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/DomainClients/City.partial.cs new file mode 100644 index 000000000..dbf3c59b3 --- /dev/null +++ b/src/OpenRiaServices.Client/Test/Client.Test/Data/DomainClients/City.partial.cs @@ -0,0 +1,81 @@ +extern alias SSmDsClient; + +using System; +using System.ComponentModel.DataAnnotations; + +namespace Cities +{ + [CustomValidation(typeof(City), "ValidateCity")] + public partial class City + { + /// + /// Initializes a new instance of a using the specified + /// state name, which can be invalid. + /// + /// + /// The state name to use for initialization. This can be + /// an invalid value, as validation won't be performed. + /// + public City(string stateName) + { + this._stateName = stateName; + } + + /// + /// Gets or sets whether or not the entity-level validation for ValidateCity should fail. + /// + internal bool ThrowValidationExceptions { get; set; } + + /// + /// Gets or sets a callback to be used whenever the ValidateProperty method is invoked. + /// + internal Action ValidatePropertyCallback { get; set; } + + /// + /// Gets or sets a callback to be used whenever the ValidateCity validation method is invoked. + /// + internal Action ValidateCityCallback { get; set; } + + /// + /// Gets or sets the count of calls to the ValidateCity method, which is an + /// entity-level validation methods. + /// + internal int ValidateCityCallCount { get; set; } + + protected override void ValidateProperty(ValidationContext context, object value) + { + this.ValidatePropertyCallback?.Invoke(context); + + if (this.ThrowValidationExceptions) + { + System.ComponentModel.DataAnnotations.Validator.ValidateProperty(value, context); + } + else + { + base.ValidateProperty(context, value); + } + } + + /// + /// Gets or sets a value indicating whether the entity-level custom validation should fail. + /// + public bool MakeEntityValidationFail { get; set; } + + public static ValidationResult ValidateCity(City entity, ValidationContext validationContext) + { + entity.ValidateCityCallback?.Invoke(validationContext); + + // Increment our call counter + ++entity.ValidateCityCallCount; + + // And if we're supposed to fail, return the failure result + if (entity.MakeEntityValidationFail) + { + return new ValidationResult("MakeEntityValidationFail is true"); + } + + // Otherwise return success + return ValidationResult.Success; + } + } +} diff --git a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityConflictTests.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/EntityConflictTests.cs similarity index 100% rename from src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityConflictTests.cs rename to src/OpenRiaServices.Client/Test/Client.Test/Data/EntityConflictTests.cs diff --git a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTests.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/EntityTests.cs similarity index 95% rename from src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTests.cs rename to src/OpenRiaServices.Client/Test/Client.Test/Data/EntityTests.cs index 64d7d5cf2..5e910535e 100644 --- a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTests.cs +++ b/src/OpenRiaServices.Client/Test/Client.Test/Data/EntityTests.cs @@ -890,57 +890,6 @@ public void Entity_RaiseDataMemberChanged_NonChangeTrackedProperty() Assert.AreEqual(2, propertyChanges.Count(p => p == "CalculatedProperty1")); } - [TestMethod] - [Asynchronous] - [TestDescription("Verifies that entity child and parent relationships are restored after RejectChanges is called.")] - [WorkItem(720495)] - public void Entity_RejectChanges_ParentAssociationRestored() - { - List employeeList = new List(); - ConfigurableEntityContainer container = new ConfigurableEntityContainer(); - container.CreateSet(EntitySetOperations.All); - ConfigurableDomainContext catalog = new ConfigurableDomainContext(new WebDomainClient(TestURIs.EFCore_Catalog), container); - - var load = catalog.Load(catalog.GetEntityQuery("GetEmployees"), throwOnError:false); - this.EnqueueCompletion(() => load); - this.EnqueueCallback(() => - { - Assert.AreEqual(null, load.Error); - - Employee parent, child; - parent = container.GetEntitySet().OrderByDescending(e => e.Reports.Count).First(); - - while (parent != null) - { - // Track parent, get a report from it - employeeList.Add(parent); - child = parent.Reports.OrderByDescending(e => e.Reports.Count).FirstOrDefault(); - - // Track child - if (child == null) - { - break; - } - - // Remove child and continue - parent.Reports.Remove(child); - parent = child; - } - - // By rejecting changes, our parent<=>child relationships should be restored. - catalog.RejectChanges(); - - // Unwind, walking up management chain - foreach (Employee employee in employeeList.Reverse()) - { - Assert.AreSame(parent, employee, "Expected parent relationship to be restored."); - parent = employee.Manager; - Assert.IsTrue(parent.Reports.Contains(employee), "Expected child relationship to be restored."); - } - }); - this.EnqueueTestComplete(); - } - [TestMethod] public void Entity_SkipIndexers() { diff --git a/src/OpenRiaServices.Client/Test/Client.Test/Data/TestHelpers.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/TestHelpers.cs index 43dd9d2ed..a993bbfb3 100644 --- a/src/OpenRiaServices.Client/Test/Client.Test/Data/TestHelpers.cs +++ b/src/OpenRiaServices.Client/Test/Client.Test/Data/TestHelpers.cs @@ -98,14 +98,6 @@ public static bool VerifyEntityState(IDictionary expectedState, } } - public class ConfigurableEntityContainer : EntityContainer - { - public void CreateSet(EntitySetOperations operations) where TEntity : Entity, new() - { - base.CreateEntitySet(operations); - } - } - /// /// Class that provides/caches database data without performing any remote queries. /// diff --git a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/ValidationResultCollectionTests.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/ValidationResultCollectionTests.cs similarity index 100% rename from src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/ValidationResultCollectionTests.cs rename to src/OpenRiaServices.Client/Test/Client.Test/Data/ValidationResultCollectionTests.cs diff --git a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/ValidationUtilitiesTests.cs b/src/OpenRiaServices.Client/Test/Client.Test/Data/ValidationUtilitiesTests.cs similarity index 100% rename from src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/ValidationUtilitiesTests.cs rename to src/OpenRiaServices.Client/Test/Client.Test/Data/ValidationUtilitiesTests.cs diff --git a/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTestsE2E.cs b/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTestsE2E.cs new file mode 100644 index 000000000..cecb3b704 --- /dev/null +++ b/src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTestsE2E.cs @@ -0,0 +1,112 @@ +extern alias SSmDsClient; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Reflection; +using Cities; +using DataTests.AdventureWorks.LTS; +using Microsoft.Silverlight.Testing; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenRiaServices.Silverlight.Testing; + +namespace OpenRiaServices.Client.Test +{ + using Resource = SSmDsClient::OpenRiaServices.Client.Resource; + using TestDescription = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute; + + [TestClass] + public class EntityTestsE2E : UnitTestBase + { + [TestMethod] + [Asynchronous] + [TestDescription("Verifies that entity child and parent relationships are restored after RejectChanges is called.")] + [WorkItem(720495)] + public void Entity_RejectChanges_ParentAssociationRestored() + { + List employeeList = new List(); + ConfigurableEntityContainer container = new ConfigurableEntityContainer(); + container.CreateSet(EntitySetOperations.All); + ConfigurableDomainContext catalog = new ConfigurableDomainContext(new WebDomainClient(TestURIs.EFCore_Catalog), container); + + var load = catalog.Load(catalog.GetEntityQuery("GetEmployees"), throwOnError:false); + this.EnqueueCompletion(() => load); + this.EnqueueCallback(() => + { + Assert.AreEqual(null, load.Error); + + Employee parent, child; + parent = container.GetEntitySet().OrderByDescending(e => e.Reports.Count).First(); + + while (parent != null) + { + // Track parent, get a report from it + employeeList.Add(parent); + child = parent.Reports.OrderByDescending(e => e.Reports.Count).FirstOrDefault(); + + // Track child + if (child == null) + { + break; + } + + // Remove child and continue + parent.Reports.Remove(child); + parent = child; + } + + // By rejecting changes, our parent<=>child relationships should be restored. + catalog.RejectChanges(); + + // Unwind, walking up management chain + foreach (Employee employee in employeeList.Reverse()) + { + Assert.AreSame(parent, employee, "Expected parent relationship to be restored."); + parent = employee.Manager; + Assert.IsTrue(parent.Reports.Contains(employee), "Expected child relationship to be restored."); + } + }); + this.EnqueueTestComplete(); + } + + private class TestCityContainer : EntityContainer + { + public TestCityContainer() + { + CreateEntitySet(EntitySetOperations.Add | EntitySetOperations.Edit | EntitySetOperations.Remove); + CreateEntitySet(EntitySetOperations.Add | EntitySetOperations.Edit | EntitySetOperations.Remove); + } + } + } + + public class ConfigurableDomainContext : DomainContext + { + private readonly EntityContainer _entityContainer; + + public ConfigurableDomainContext(DomainClient client, EntityContainer entityContainer) + : base(client) + { + this._entityContainer = entityContainer; + } + + public EntityQuery GetEntityQuery(string queryName) where TEntity : Entity + { + return this.CreateQuery(queryName, null, false, false); + } + + protected override EntityContainer CreateEntityContainer() + { + return this._entityContainer; + } + } + + public class ConfigurableEntityContainer : EntityContainer + { + public void CreateSet(EntitySetOperations operations) where TEntity : Entity, new() + { + base.CreateEntitySet(operations); + } + } + +}