Esempio n. 1
0
        public async Task Should_Use_DefaultErrorMapper()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
            {
                builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                .AddMutationType(new TestUseDefaultErrorMapperMutation());
            },
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            Assert.Collection(result.Errors,
                              name =>
            {
                Assert.Equal(ValidationDefaults.Code, name.Code);
                Assert.Equal(NotEmptyNameValidator.Message, name.Message);

                Assert.Collection(name.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            });
        }
        public async Task UseValidatorGenericWithValidationStrategy()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.UseValidator <IValidator <TestPersonInput> >(strategy =>
                    {
                        strategy.IncludeProperties("NotExists");
                    });
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>()
                .AddTransient <IValidator <TestPersonInput>, NotEmptyAddressValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
        public async Task Should_Execute_SkipValidation_WithCustomValidator()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.SkipValidation()
                    .UseInputValidators(async context =>
                    {
                        var argumentValue = context.MiddlewareContext.ArgumentValue <TestPersonInput>(context.Argument.Name);

                        return(await new NotEmptyNameValidator().ValidateAsync(argumentValue));
                    });
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 4
0
        public async Task ThrowsNoMessageSet()
        {
            var executor = await TestSetup.CreateRequestExecutor(
                builder =>
            {
                builder.AddFluentValidation(opt => opt.UseErrorMapper(ValidationDefaults.ErrorMappers.Details))
                .AddMutationType(new TestMutation(field =>
                {
                    field.Argument("input",
                                   arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                    {
                        opt.UseValidator <NotEmptyNameValidator>();
                    }));
                }));
            },
                services =>
            {
                services.AddTransient <NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.IsType <InvalidOperationException>(error.Exception);
        }
        public async Task UseValidatorsGenericWithInputParameter()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.UseValidators <TestPersonInput, IValidator <TestPersonInput> >();
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>()
                .AddTransient <IValidator <TestPersonInput>, NotEmptyAddressValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            Assert.Collection(result.Errors,
                              nameIsEmpty => Assert.Equal(NotEmptyNameValidator.Message, nameIsEmpty.Message),
                              addressIsEmpty => Assert.Equal(NotEmptyAddressValidator.Message, addressIsEmpty.Message));
        }
        public async Task GlobalSkipValidationFieldOverride()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt => opt.SkipValidation(ValidationDefaults.SkipValidation.Default))
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.SkipValidation(ValidationDefaults.SkipValidation.Skip);
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 7
0
        public async Task UseValidatorsOverrideFullWithValidationStrategy()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input", arg => arg.Type <TestPersonInputType>().UseFluentValidation(opt =>
                {
                    opt.UseValidators <TestPersonInput, IValidator <TestPersonInput> >
                        (strategy => strategy.IncludeProperties("Name"));
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, DoubleNotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithNullInput));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 8
0
        public async Task NoInputs()
        {
            var executor = await TestSetup.CreateRequestExecutor(
                builder =>
            {
                builder.AddFluentValidation()
                .AddMutationType(new TestMutation(field =>
                {
                    field.Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >())
                    .Argument("input2", arg => arg.Type <TestPersonInputType>());
                }));
            },
                services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyNameAndSecondInput));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 9
0
        public async Task Should_Execute_GlobalSkipValidation_Predecate()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt =>
            {
                opt.SkipValidation(context => new ValueTask <bool>(context.Argument.Name == "input"));
            })
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation());
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 10
0
        public async Task SecondInput()
        {
            var executor = await TestSetup.CreateRequestExecutor(
                builder =>
            {
                builder.AddFluentValidation()
                .AddMutationType(new TestMutation(field =>
                {
                    field.Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >())
                    .Argument("input2", arg => arg.Type <TestPersonInputType>().UseFluentValidation());
                }));
            },
                services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyNameAndSecondInput));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.Equal(ValidationDefaults.Code, error.Code);
            Assert.Equal(NotEmptyNameValidator.Message, error.Message);

            Assert.Collection(error.Extensions,
                              code =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                Assert.Equal(ValidationDefaults.Code, code.Value);
            });
        }
Esempio n. 11
0
        public async Task MultipleErrorMappers()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.UseDefaultErrorMapper()
                    .UseDefaultErrorMapperWithDetails();
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.Equal(ValidationDefaults.Code, error.Code);
            Assert.Equal(NotEmptyNameValidator.Message, error.Message);

            Assert.Collection(error.Extensions,
                              code =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                Assert.Equal(ValidationDefaults.Code, code.Value);
            },
                              validator =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.ValidatorKey, validator.Key);
                Assert.Equal("NotEmptyValidator", validator.Value);
            },
                              field =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.FieldKey, field.Key);
                Assert.Equal(new NameString("test"), field.Value);
            },
                              argument =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.ArgumentKey, argument.Key);
                Assert.Equal(new NameString("input"), argument.Value);
            },
                              property =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.PropertyKey, property.Key);
                Assert.Equal("Name", property.Value);
            },
                              severity =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.SeverityKey, severity.Key);
                Assert.Equal(Severity.Error, severity.Value);
            });
        }
        public async Task Should_Use_Multiple_InputValidator()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field => field
                                                                                                   .Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >()
                                                                                                             .UseFluentValidation(opt =>
            {
                opt.UseDefaultInputValidator(async context =>
                {
                    var validator = new NotEmptyAddressValidator();

                    var argumentValue = context.MiddlewareContext.ArgumentValue <TestPersonInput>(context.Argument.Name);

                    return(await validator
                           .ValidateAsync(argumentValue, context.MiddlewareContext.RequestAborted)
                           .ConfigureAwait(false));
                });
            })))),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            Assert.Collection(result.Errors,
                              name =>
            {
                Assert.Equal(ValidationDefaults.Code, name.Code);
                Assert.Equal(NotEmptyNameValidator.Message, name.Message);

                Assert.Collection(name.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            },
                              address =>
            {
                Assert.Equal(ValidationDefaults.Code, address.Code);
                Assert.Equal(NotEmptyAddressValidator.Message, address.Message);

                Assert.Collection(address.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            });
        }
        public async Task Should_UseMultipleCustomValidators_SameProperty()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.UseValidator <NotEmptyNameValidator>()
                    .UseValidator <NotEmptyNameValidator>();
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <NotEmptyNameValidator>().AddTransient <NotEmptyAddressValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            Assert.Collection(result.Errors,
                              name =>
            {
                Assert.Equal(ValidationDefaults.Code, name.Code);
                Assert.Equal(NotEmptyNameValidator.Message, name.Message);

                Assert.Collection(name.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            },
                              name =>
            {
                Assert.Equal(ValidationDefaults.Code, name.Code);
                Assert.Equal(NotEmptyNameValidator.Message, name.Message);

                Assert.Collection(name.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            });
        }
Esempio n. 14
0
        public async Task Should_Pass_Values_UseFluentValidation()
        {
            var executor = await TestSetup.CreateRequestExecutor(
                builder =>
            {
                builder.AddFluentValidation()
                .AddMutationType(new TestMutation(field =>
                {
                    field.Argument("input", arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                    {
                        opt.UseDefaultErrorMapper(
                            (_, context) =>
                        {
                            Assert.Equal("input", context.Argument.Name);
                            Assert.Single(context.ValidationResult.Errors);
                            Assert.Equal(nameof(TestPersonInput.Name), context.ValidationFailure.PropertyName);
                        });
                    }));
                }));
            },
                services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.Equal(ValidationDefaults.Code, error.Code);
            Assert.Equal(NotEmptyNameValidator.Message, error.Message);

            Assert.Collection(error.Extensions,
                              code =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                Assert.Equal(ValidationDefaults.Code, code.Value);
            });
        }
Esempio n. 15
0
        public async Task UseValidatorsWithValidationStrategyAddress()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
            {
                builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                .AddMutationType(new TestUseValidatorsWithValidationStrategyAddressMutation());
            },
                                                                 services =>
            {
                services.AddTransient <NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 16
0
        public async Task Should_CustomSkipValidation_Skip()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
            {
                builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                .AddMutationType(new TestCustomSkipValidationMutation());
            },
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithName("Custom")));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
Esempio n. 17
0
        public async Task UseValidatorWithValidationStrategy()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input",
                               arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
                {
                    opt.UseValidator <NotEmptyNameValidator>()
                    .UseValidator <TestPersonInput, NotEmptyAddressValidator>(strategy =>
                                                                              // Validates address, but includes only name
                                                                              strategy.IncludeProperties(input => input.Name));
                }));
            })),
                                                                 services =>
            {
                services.AddTransient <NotEmptyNameValidator>().AddTransient <NotEmptyAddressValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyNameAndAddress));

            result.AssertNullResult();

            Assert.Collection(result.Errors,
                              name =>
            {
                Assert.Equal(ValidationDefaults.Code, name.Code);
                Assert.Equal(NotEmptyNameValidator.Message, name.Message);

                Assert.Collection(name.Extensions,
                                  code =>
                {
                    Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                    Assert.Equal(ValidationDefaults.Code, code.Value);
                });
            });
        }
Esempio n. 18
0
        public async Task Should_HaveNullResult_ValidationError_ExtensionCodes()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation()
                                                                 .AddMutationType(new TestMutation(field =>
            {
                field.Argument("input", arg => arg.Type <TestPersonInputType>().UseFluentValidation());
            })),
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithNullInput));

            var(key, value) = Assert.Single(result.Data);

            Assert.Equal("test", key);
            Assert.Equal("test", value);

            Assert.Null(result.Errors);
        }
        public async Task Should_UseCustomValidator()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
                                                                 builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                                                                 .AddMutationType(new TestMutation(field => field.Argument("input",
                                                                                                                           arg => arg.Type <NonNullType <TestPersonInputType> >().UseFluentValidation(opt =>
            {
                opt.UseInputValidators(async context =>
                {
                    var argumentValue = context.MiddlewareContext.ArgumentValue <TestPersonInput>(context.Argument.Name);

                    return(await new NotEmptyNameValidator().ValidateAsync(argumentValue));
                });
            })))),
                                                                 services =>
            {
                services.AddTransient <NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.Equal(ValidationDefaults.Code, error.Code);
            Assert.Equal(NotEmptyNameValidator.Message, error.Message);

            Assert.Collection(error.Extensions,
                              code =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                Assert.Equal(ValidationDefaults.Code, code.Value);
            });
        }
Esempio n. 20
0
        public async Task Should_Use_DefaultErrorMapperWithExtendedDetails()
        {
            var executor = await TestSetup.CreateRequestExecutor(builder =>
            {
                builder.AddFluentValidation(opt => opt.UseDefaultErrorMapper())
                .AddMutationType(new TestUseDefaultErrorMapperWithExtendedDetailsMutation());
            },
                                                                 services =>
            {
                services.AddTransient <IValidator <TestPersonInput>, NotEmptyNameValidator>();
            });

            var result = Assert.IsType <QueryResult>(
                await executor.ExecuteAsync(TestSetup.Mutations.WithEmptyName));

            result.AssertNullResult();

            var error = Assert.Single(result.Errors);

            Assert.Equal(ValidationDefaults.Code, error.Code);
            Assert.Equal(NotEmptyNameValidator.Message, error.Message);

            Assert.Collection(error.Extensions,
                              code =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CodeKey, code.Key);
                Assert.Equal(ValidationDefaults.Code, code.Value);
            },
                              validator =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.ValidatorKey, validator.Key);
                Assert.Equal("NotEmptyValidator", validator.Value);
            },
                              field =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.FieldKey, field.Key);
                Assert.Equal(new NameString("test"), field.Value);
            },
                              argument =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.ArgumentKey, argument.Key);
                Assert.Equal(new NameString("input"), argument.Value);
            },
                              property =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.PropertyKey, property.Key);
                Assert.Equal("Name", property.Value);
            },
                              severity =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.SeverityKey, severity.Key);
                Assert.Equal(Severity.Error, severity.Value);
            },
                              attemptedValue =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.AttemptedValueKey, attemptedValue.Key);
                Assert.Equal("", attemptedValue.Value);
            },
                              customState =>
            {
                Assert.Equal(ValidationDefaults.ExtensionKeys.CustomStateKey, customState.Key);
                Assert.Null(customState.Value);
            },
                              formattedMessagePlaceholerValues =>
            {
                Assert.Equal(
                    ValidationDefaults.ExtensionKeys.FormattedMessagePlaceholderValuesKey,
                    formattedMessagePlaceholerValues.Key);

                var values = Assert.IsType <Dictionary <string, object> >(formattedMessagePlaceholerValues.Value);

                Assert.Collection(values,
                                  propertyName =>
                {
                    Assert.Equal("PropertyName", Assert.IsType <string>(propertyName.Key));
                    Assert.Equal("Name", Assert.IsType <string>(propertyName.Value));
                },
                                  propertyValue =>
                {
                    Assert.Equal("PropertyValue", Assert.IsType <string>(propertyValue.Key));
                    Assert.Equal("", Assert.IsType <string>(propertyValue.Value));
                });
            });
        }