public void NamedUpdate_CustomValidation_NoEntityValidation() { string methodName = "NamedUpdateWithNoEntityValidation"; MockComplexObject2 complexObject = new MockComplexObject2(); string format1 = "{0} invalid on client."; ValidationResult registeredResult = CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject2)); ValidationResult expectedClientResult = CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject2), true, methodName + ".complexObject.PlaceholderName"); SubmitOperation submitOp = null; LoadOperation<MockEntity6> loadOp = null; MockEntity6 entity = null; Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = null; this.EnqueueCallback(() => { ctx = new NamedUpdate_CustomValidation(uri); loadOp = ctx.Load(ctx.GetEntities6Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); // Make the param invalid and the call should fail. DynamicTestValidator.ForcedValidationResults.Add(typeof(MockComplexObject2), registeredResult); ExceptionHelper.ExpectValidationException(() => { entity.NamedUpdateWithNoEntityValidation(complexObject); }, expectedClientResult.ErrorMessage, typeof(CustomValidationAttribute), complexObject); DynamicTestValidator.Reset(); entity.NamedUpdateWithNoEntityValidation(complexObject); // This time the client submit should fail. DynamicTestValidator.ForcedValidationResults.Add(typeof(MockComplexObject2), registeredResult); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "Client call: Submit should have failed."); UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { expectedClientResult }, entity.ValidationErrors); // Now the server submit should fail. DynamicTestValidator.Reset(); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "Server call: Submit should have failed."); var expectedServerResults = CustomMethodTests.GetExpectedErrors(methodName); UnitTestHelper.AssertValidationResultsAreEqual(expectedServerResults, entity.ValidationErrors); }); this.EnqueueTestComplete(); }
public void NamedUpdate_CustomValidation_CommonProperties() { string methodName = "NamedUpdateWithCommonProperties"; MockComplexObject3 complexObject = CustomMethodTests.CreateMockComplexObject3(); SubmitOperation submitOp = null; LoadOperation<MockEntity5> loadOp = null; MockEntity5 entity = null; Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = null; Action<MockComplexObject4, ValidationResult, ValidationResult> paramVariation = (invalidObject, registeredResult, expectedClientResult) => { this.EnqueueCallback(() => { ctx = new NamedUpdate_CustomValidation(uri); loadOp = ctx.Load(ctx.GetEntities5Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); entity.NamedUpdateWithCommonProperties(complexObject); // Make only the ComplexObject's property invalid. This should produce an error // that can't be pushed down into the entity's property's collection. DynamicTestValidator.ForcedValidationResults.Add(invalidObject, registeredResult); // Submit and watch it fail. submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "Client call: Submit should have failed."); // The client should fail validation of only the argument's property. Assert.AreEqual(1, entity.ValidationErrors.Count(), "Client call: Entity should have an error."); Assert.AreEqual(0, entity.CommonProperty.ValidationErrors.Count(), "Client call: Validation error was pushed down to property."); Assert.AreEqual(0, entity.CommonArray[0].ValidationErrors.Count(), "Client call: Validation error was pushed down to array."); // Reset the validator and get the result from the server. DynamicTestValidator.Reset(); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "Server call: Submit should have failed."); // The server should fail validation of all MockEntity4 types. IEnumerable<ValidationResult> expectedServerValidationResults = CustomMethodTests.GetExpectedErrors(methodName); UnitTestHelper.AssertValidationResultsAreEqual(expectedServerValidationResults, entity.ValidationResultCollection); Assert.AreEqual(1, entity.CommonProperty.ValidationErrors.Count(), "Server call: Validation error was pushed down to property."); // Errors cannot get pushed to arrays. Assert.AreEqual(0, entity.CommonArray[0].ValidationErrors.Count(), "Server call: Validation error was pushed down to array."); }); }; string format1 = "{0} invalid on client."; string paramPrefix = methodName + ".complexObject."; paramVariation(complexObject.CommonProperty, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject4), "CommonProperty.PlacehoderName"), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject4), false, "CommonProperty.PlacehoderName")); paramVariation(complexObject.CommonProperty.Property1, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject4), "CommonProperty.Property1.PlacehoderName"), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject4), false, "CommonProperty.Property1.PlacehoderName")); paramVariation(complexObject.CommonArray[0], CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject4), "CommonArray().PlacehoderName"), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject4), false, paramPrefix + "CommonArray().PlacehoderName")); paramVariation(complexObject.CommonArray[0].Property1, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject4), "CommonArray().Property1.PlacehoderName"), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject4), false, paramPrefix + "CommonArray().Property1.PlacehoderName")); this.EnqueueTestComplete(); }
public void NamedUpdate_CustomValidation_Property() { MockComplexObject1[] complexArray = new MockComplexObject1[] { new MockComplexObject1() { } }; MockComplexObject1 complexObject = new MockComplexObject1 { Property1 = new MockComplexObject1() }; SubmitOperation submitOp = null; LoadOperation<MockEntity3> loadOp = null; MockEntity3 entity = null; Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = null; Action<object, ValidationResult, ValidationResult, ValidationResult> paramVariation = (invalidParam, registeredResult, expectedClientResult, expectedServerResult) => { this.EnqueueCallback(() => { ctx = new NamedUpdate_CustomValidation(uri); loadOp = ctx.Load(ctx.GetEntities3Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); // reset property values entity.ValidatedProperty = null; complexArray[0].ValidatedProperty = null; complexObject.ValidatedProperty = null; complexObject.Property1.ValidatedProperty = null; // make the correct param invalid. string invalidProperty = "Invalid"; bool deepValidation; if (invalidParam == null) { entity.ValidatedProperty = invalidProperty; deepValidation = false; } else if (invalidParam == complexArray) { complexArray[0].ValidatedProperty = invalidProperty; deepValidation = true; } else if (invalidParam == complexObject) { complexObject.ValidatedProperty = invalidProperty; deepValidation = false; } else { complexObject.Property1.ValidatedProperty = invalidProperty; deepValidation = true; } // make property invalid DynamicTestValidator.Reset(); DynamicTestValidator.ForcedValidationResults.Add(invalidProperty, registeredResult); // deep property validation should not throw on call if (deepValidation) { entity.NamedUpdateWithPropValidation(complexArray, complexObject); ctx.MockEntity3s.Clear(); entity.Reset(); ctx.MockEntity3s.Attach(entity); } // shallow property validation should throw on call else { ValidationException vex = ExceptionHelper.ExpectValidationException(() => { entity.NamedUpdateWithPropValidation(complexArray, complexObject); }, expectedClientResult.ErrorMessage, typeof(CustomValidationAttribute), invalidProperty); // The exception varies from the expected because the framework does not alter the result. // This means the expected MemberNames is equivalent to the registered MemberNames UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { new ValidationResult(expectedClientResult.ErrorMessage, registeredResult.MemberNames) }, new ValidationResult[] { vex.ValidationResult }); } // ensure property validation fails on client submit DynamicTestValidator.Reset(); entity.NamedUpdateWithPropValidation(complexArray, complexObject); // make param invalid once again DynamicTestValidator.ForcedValidationResults.Add(invalidProperty, registeredResult); // actually submit submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on client submit of an incorrect entity."); // compare to expected UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { expectedClientResult }, entity.ValidationResultCollection); // ensure property validation fails on server submit DynamicTestValidator.Reset(); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on server submit of an incorrect entity."); // compare to expected IEnumerable<ValidationResult> expectedServerValidationResults = new ValidationResult[] { expectedServerResult }; UnitTestHelper.AssertValidationResultsAreEqual(expectedServerValidationResults, entity.ValidationResultCollection); }); }; // Run variations string clientFormat1 = "{0} invalid on the client"; string propName = "ValidatedProperty"; string serverErrorMessage = DynamicTestValidator.GetMemberError("Property validation failed.", propName); string methodName = "NamedUpdateWithPropValidation."; paramVariation(null, CustomMethodTests.CreateRegisteredValidationResult(clientFormat1, propName), CustomMethodTests.CreateExpectedPropertyValidationResult(clientFormat1, propName), CustomMethodTests.CreateExpectedValidationResult(serverErrorMessage, propName)); string memberPath = methodName + "array()"; paramVariation(complexArray, CustomMethodTests.CreateRegisteredValidationResult(clientFormat1, propName), CustomMethodTests.CreateExpectedPropertyValidationResult(clientFormat1, propName, memberPath), CustomMethodTests.CreateExpectedValidationResult(serverErrorMessage, propName, memberPath)); memberPath = methodName + "complexObject"; paramVariation(complexObject, CustomMethodTests.CreateRegisteredValidationResult(clientFormat1, propName), CustomMethodTests.CreateExpectedPropertyValidationResult(clientFormat1, propName, memberPath), CustomMethodTests.CreateExpectedValidationResult(serverErrorMessage, propName, memberPath)); memberPath = methodName + "complexObject.Property1"; paramVariation(complexObject.Property1, CustomMethodTests.CreateRegisteredValidationResult(clientFormat1, propName), CustomMethodTests.CreateExpectedPropertyValidationResult(clientFormat1, propName, memberPath), CustomMethodTests.CreateExpectedValidationResult(serverErrorMessage, propName, memberPath)); this.EnqueueTestComplete(); }
public void NamedUpdate_CustomValidation_Type() { MockComplexObject2[] complexArray = new MockComplexObject2[] { new MockComplexObject2() }; MockComplexObject2 complexObject = new MockComplexObject2 { Property1 = new MockComplexObject2() }; SubmitOperation submitOp = null; LoadOperation<MockEntity4> loadOp = null; MockEntity4 entity = null; Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = null; Action<object, bool, ValidationResult, ValidationResult> typeVariation = (invalidParam, deepValidation, registeredResult, expectedResult) => { this.EnqueueCallback(() => { ctx = new NamedUpdate_CustomValidation(uri); loadOp = ctx.Load(ctx.GetEntities4Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); if (invalidParam == null) { invalidParam = entity; } // make param invalid DynamicTestValidator.Reset(); DynamicTestValidator.ForcedValidationResults.Add(invalidParam, registeredResult); // deep type validation should not throw on call if (deepValidation) { entity.NamedUpdateWithTypeValidation(complexArray, complexObject); ctx.MockEntity4s.Clear(); entity.Reset(); ctx.MockEntity4s.Attach(entity); } // shallow type validation should throw on call else { ValidationException vex = ExceptionHelper.ExpectValidationException(() => { entity.NamedUpdateWithTypeValidation(complexArray, complexObject); }, expectedResult.ErrorMessage, typeof(CustomValidationAttribute), invalidParam); // The exception varies from the expected because the framework does not alter the result. // This means the expected MemberNames is equivalent to the registered MemberNames UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { new ValidationResult(expectedResult.ErrorMessage, registeredResult.MemberNames) }, new ValidationResult[] { vex.ValidationResult }); } // ensure type validation fails on client submit DynamicTestValidator.Reset(); entity.NamedUpdateWithTypeValidation(complexArray, complexObject); // make param invalid once again DynamicTestValidator.ForcedValidationResults.Add(invalidParam, registeredResult); // actually submit submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on client submit of an incorrect entity."); // compare to expected UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { expectedResult }, entity.ValidationResultCollection); // ensure type validation fails on server submit DynamicTestValidator.Reset(); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on server submit of an incorrect entity."); // compare to expected, the server errors no matter what we send it, so its // expected validation failures can be static. IEnumerable<ValidationResult> expectedServerValidationResults = CustomMethodTests.GetExpectedErrors("NamedUpdateWithTypeValidation"); UnitTestHelper.AssertValidationResultsAreEqual(expectedServerValidationResults, entity.ValidationResultCollection); }); }; // Run variations string format1 = "{0} invalid on the client"; typeVariation(null, false, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockEntity4)), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockEntity4), false)); typeVariation(complexArray[0], true, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject2)), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject2), false, "NamedUpdateWithTypeValidation.array().PlaceholderName")); typeVariation(complexObject, false, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject2)), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject2), false, "NamedUpdateWithTypeValidation.complexObject.PlaceholderName")); typeVariation(complexObject.Property1, true, CustomMethodTests.CreateRegisteredValidationResult(format1, typeof(MockComplexObject2)), CustomMethodTests.CreateExpectedValidationResult(format1, typeof(MockComplexObject2), false, "NamedUpdateWithTypeValidation.complexObject.Property1.PlaceholderName")); this.EnqueueTestComplete(); }
public void NamedUpdate_CustomValidation_Parameter() { MockComplexObject1[] complexArray = new MockComplexObject1[] { new MockComplexObject1() }; MockComplexObject1 complexObject = new MockComplexObject1 { Property1 = new MockComplexObject1() }; Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = null; MockEntity3 entity = null; LoadOperation<MockEntity3> loadOp = null; SubmitOperation submitOp = null; // The core body of the test. This delegate can be called multiple times. Action<object, ValidationResult, ValidationResult> paramVariation = (invalidParam, registeredResult, expectedResult) => { this.EnqueueCallback(() => { ctx = new NamedUpdate_CustomValidation(uri); loadOp = ctx.Load(ctx.GetEntities3Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); // make param invalid DynamicTestValidator.Reset(); DynamicTestValidator.ForcedValidationResults.Add(invalidParam.GetType(), registeredResult); // param validation should throw on call ValidationException vex = ExceptionHelper.ExpectValidationException(() => { entity.NamedUpdateWithParamValidation(complexArray, complexObject); }, expectedResult.ErrorMessage, typeof(CustomValidationAttribute), invalidParam); // The exception varies from the expected because the framework does not alter the result. // This means the expected MemberNames is equivalent to the registered MemberNames UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { new ValidationResult(expectedResult.ErrorMessage, registeredResult.MemberNames) }, new ValidationResult[] { vex.ValidationResult }); // ensure param validation fails on client submit DynamicTestValidator.Reset(); entity.NamedUpdateWithParamValidation(complexArray, complexObject); // make param invalid once again DynamicTestValidator.ForcedValidationResults.Add(invalidParam.GetType(), registeredResult); // actually submit submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on client submit of an incorrect param."); // compare to expected UnitTestHelper.AssertValidationResultsAreEqual(new ValidationResult[] { expectedResult }, entity.ValidationResultCollection); // ensure param validation fails on server submit DynamicTestValidator.Reset(); submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { Assert.IsTrue(submitOp.HasError, "No error on server submit of an incorrect param."); // compare to expected, the server errors no matter what we send it, so its // expected validation failures can be static. IEnumerable<ValidationResult> expectedServerValidationResults = CustomMethodTests.GetExpectedErrors("NamedUpdateWithParamValidation"); UnitTestHelper.AssertValidationResultsAreEqual(expectedServerValidationResults, entity.ValidationResultCollection); }); }; string format1 = "{0} invalid on the client"; // Run variations paramVariation(complexArray, CreateRegisteredValidationResult(format1, complexArray.GetType()), CreateExpectedValidationResult(format1, complexArray.GetType(), true, "NamedUpdateWithParamValidation.array().PlaceholderName")); paramVariation(complexObject, CreateRegisteredValidationResult(format1, complexObject.GetType()), CreateExpectedValidationResult(format1, complexObject.GetType(), true, "NamedUpdateWithParamValidation.complexObject.PlaceholderName")); this.EnqueueTestComplete(); }
public void NamedUpdate_CustomValidation_Entity_Parameter() { string clientInvalidProperty = "Invalid on client"; MockComplexObject1[] complexArray = new MockComplexObject1[] { new MockComplexObject1() }; MockComplexObject1 recursiveComplexObject = new MockComplexObject1 { Property1 = new MockComplexObject1() }; string[] memberNames = new string[] { "PlaceholderName" }; ValidationResult expectedClientValidationResult = new ValidationResult(clientInvalidProperty, memberNames); Uri uri = new Uri(TestURIs.RootURI, "TestDomainServices-NamedUpdates-NamedUpdate_CustomValidation.svc"); NamedUpdate_CustomValidation ctx = new NamedUpdate_CustomValidation(uri); MockEntity3 entity = null; LoadOperation<MockEntity3> loadOp = null; SubmitOperation submitOp = null; this.EnqueueCallback(() => { loadOp = ctx.Load(ctx.GetEntities3Query(), TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => loadOp.IsComplete); this.EnqueueCallback(() => { TestHelperMethods.AssertOperationSuccess(loadOp); entity = loadOp.Entities.First(); // make entity param invalid DynamicTestValidator.Reset(); DynamicTestValidator.ForcedValidationResults.Add(typeof(MockEntity3), expectedClientValidationResult); DynamicTestValidator.Monitor(true); // entity param validation should not be run during the call entity.NamedUpdateWithParamValidation(complexArray, recursiveComplexObject); // entity param validation should not be run during the submit on the client side submitOp = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null); }); this.EnqueueConditional(() => submitOp.IsComplete); this.EnqueueCallback(() => { // the server fails all params Assert.IsTrue(submitOp.HasError, "Error on client submit of an incorrect entity."); // check that param validation was not run on the client // note, entity has no param name so we cannot check for it directly Assert.IsFalse(DynamicTestValidator.ValidationCalls.Where(vc => vc.DisplayName != "array" && vc.DisplayName != "complexObject" && vc.DisplayName != "ValidatedProperty").Any(), "Entity underwent param validation."); // check that the param validtion was run on the server IEnumerable<ValidationResult> expectedServerValidationResult = CustomMethodTests.GetExpectedErrors("NamedUpdateWithParamValidation"); UnitTestHelper.AssertValidationResultsAreEqual(expectedServerValidationResult, entity.ValidationResultCollection); }); this.EnqueueTestComplete(); }