Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move more tests from EndToEnd tests to Client.Test #454

Merged
merged 3 commits into from
Nov 2, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
extern alias SSmDsClient;

using System;
using System.ComponentModel.DataAnnotations;

namespace Cities
{
[CustomValidation(typeof(City), "ValidateCity")]
public partial class City
{
/// <summary>
/// Initializes a new instance of a <see cref="City"/> using the specified
/// state name, which can be invalid.
/// </summary>
/// <param name="stateName">
/// The state name to use for initialization. This can be
/// an invalid value, as validation won't be performed.
/// </param>
public City(string stateName)
{
this._stateName = stateName;
}

/// <summary>
/// Gets or sets whether or not the entity-level validation for ValidateCity should fail.
/// </summary>
internal bool ThrowValidationExceptions { get; set; }

/// <summary>
/// Gets or sets a callback to be used whenever the ValidateProperty method is invoked.
/// </summary>
internal Action<ValidationContext> ValidatePropertyCallback { get; set; }

/// <summary>
/// Gets or sets a callback to be used whenever the ValidateCity validation method is invoked.
/// </summary>
internal Action<ValidationContext> ValidateCityCallback { get; set; }

/// <summary>
/// Gets or sets the count of calls to the ValidateCity method, which is an
/// entity-level validation methods.
/// </summary>
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);
}
}

/// <summary>
/// Gets or sets a value indicating whether the entity-level custom validation should fail.
/// </summary>
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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Employee> employeeList = new List<Employee>();
ConfigurableEntityContainer container = new ConfigurableEntityContainer();
container.CreateSet<Employee>(EntitySetOperations.All);
ConfigurableDomainContext catalog = new ConfigurableDomainContext(new WebDomainClient<TestDomainServices.LTS.Catalog.ICatalogContract>(TestURIs.EFCore_Catalog), container);

var load = catalog.Load(catalog.GetEntityQuery<Employee>("GetEmployees"), throwOnError:false);
this.EnqueueCompletion(() => load);
this.EnqueueCallback(() =>
{
Assert.AreEqual(null, load.Error);

Employee parent, child;
parent = container.GetEntitySet<Employee>().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<Employee>())
{
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()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,6 @@ public static bool VerifyEntityState(IDictionary<string, object> expectedState,
}
}

public class ConfigurableEntityContainer : EntityContainer
{
public void CreateSet<TEntity>(EntitySetOperations operations) where TEntity : Entity, new()
{
base.CreateEntitySet<TEntity>(operations);
}
}

/// <summary>
/// Class that provides/caches database data without performing any remote queries.
/// </summary>
Expand Down
112 changes: 112 additions & 0 deletions src/Test/OpenRiaservices.EndToEnd.Wcf.Test/Data/EntityTestsE2E.cs
Original file line number Diff line number Diff line change
@@ -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<Employee> employeeList = new List<Employee>();
ConfigurableEntityContainer container = new ConfigurableEntityContainer();
container.CreateSet<Employee>(EntitySetOperations.All);
ConfigurableDomainContext catalog = new ConfigurableDomainContext(new WebDomainClient<TestDomainServices.LTS.Catalog.ICatalogContract>(TestURIs.EFCore_Catalog), container);

var load = catalog.Load(catalog.GetEntityQuery<Employee>("GetEmployees"), throwOnError:false);
this.EnqueueCompletion(() => load);
this.EnqueueCallback(() =>
{
Assert.AreEqual(null, load.Error);

Employee parent, child;
parent = container.GetEntitySet<Employee>().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<Employee>())
{
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<City>(EntitySetOperations.Add | EntitySetOperations.Edit | EntitySetOperations.Remove);
CreateEntitySet<County>(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<TEntity> GetEntityQuery<TEntity>(string queryName) where TEntity : Entity
{
return this.CreateQuery<TEntity>(queryName, null, false, false);
}

protected override EntityContainer CreateEntityContainer()
{
return this._entityContainer;
}
}

public class ConfigurableEntityContainer : EntityContainer
{
public void CreateSet<TEntity>(EntitySetOperations operations) where TEntity : Entity, new()
{
base.CreateEntitySet<TEntity>(operations);
}
}

}