public void BindingContractMismatch() { Attr1 a1 = new Attr1 { Path = "{name}" }; try { var cloner = new AttributeCloner<Attr1>(a1, EmptyContract); Assert.True(false, "Should have caught binding contract mismatch"); } catch (InvalidOperationException e) { Assert.Equal("No binding parameter exists for 'name'.", e.Message); } }
public void Setting() { Attr2 a2 = new Attr2(string.Empty, string.Empty) { ResolvedSetting = "appsetting" }; var nameResolver = new FakeNameResolver(); var config = TestHelpers.CreateInMemoryCollection() .AddSetting("appsetting", "ABC") .AddSetting("connectionStrings:default", "fromConnStr") .BuildConfiguration(); var cloner = new AttributeCloner <Attr2>(a2, emptyContract, config, nameResolver); var a2Cloned = cloner.GetNameResolvedAttribute(); Assert.Equal("ABC", a2Cloned.ResolvedSetting); Assert.Equal("fromConnStr", a2Cloned.Connection); }
public void Easy() { Attr1 a1 = new Attr1 { Path = "{request.headers.authorization}-{key2}" }; Dictionary <string, object> values = new Dictionary <string, object>() { { "request", new { headers = new { authorization = "ey123" } } }, { "key2", "val2" } }; var ctx = GetCtx(values); var cloner = new AttributeCloner <Attr1>(a1, GetBindingContract("request", "key2")); var attr2 = cloner.ResolveFromBindingData(ctx); Assert.Equal("ey123-val2", attr2.Path); }
public void AppSettingAttribute_ResolvesWholeValueAsSetting() { Attr4 a4 = new Attr4(); var name = "test{x}and%y%"; a4.AppSetting = a4.AutoResolve = name; var nameResolver = new FakeNameResolver() .Add("y", "Setting"); var config = TestHelpers.CreateInMemoryCollection() .AddSetting(name, "AppSetting") .BuildConfiguration(); var cloner = new AttributeCloner <Attr4>(a4, GetBindingContract("x"), config, nameResolver); var cloned = cloner.GetNameResolvedAttribute(); // autoresolve resolves tokens Assert.Equal("test{x}andSetting", cloned.AutoResolve); // appsetting treats entire string as app setting name Assert.Equal("AppSetting", cloned.AppSetting); }
public void ConnectionStringAttribute_ResolvesCorrectly() { ConnectionStrings attr = new ConnectionStrings { Connection = "key", ConnectionAtRoot = "rootKey", ConnectionWithNestedPath = "nested:path:key", ConnectionOverrideDefault = "overridden", ConnectionNameResolver = "%nameResolver%" }; var config = TestHelpers.CreateInMemoryCollection() .AddSetting("key", "unused") .AddSetting("rootKey", "rootValue") .AddSetting("connectionStrings:key", "connectionStringsValue") .AddSetting("nested:path:key", "nestedPathValue") .AddSetting("nested:path:defaultKey", "nestedPathDefaultValue") .AddSetting("connectionStrings:overridden", "connectionStringsOverriddenValue") .AddSetting("connectionStrings:defaultSetting", "fromConnStr") .AddSetting("defaultSetting", "fromRoot") .AddSetting("connectionStrings:resolved", "fromNameResolver") .BuildConfiguration(); var nameResolver = new FakeNameResolver(); nameResolver.Add("nameResolver", "connectionStrings:resolved"); var cloner = new AttributeCloner <ConnectionStrings>(attr, emptyContract, config, nameResolver); var cloned = cloner.GetNameResolvedAttribute(); Assert.Equal("connectionStringsValue", cloned.Connection); Assert.Equal("rootValue", cloned.ConnectionAtRoot); Assert.Equal("nestedPathValue", cloned.ConnectionWithNestedPath); Assert.Equal("connectionStringsOverriddenValue", cloned.ConnectionOverrideDefault); Assert.Equal("nestedPathDefaultValue", cloned.ConnectionWithNestedDefaultPath); Assert.Equal("fromConnStr", cloned.ConnectionWithDefault); Assert.Equal("fromRoot", cloned.AppSettingWithDefault); Assert.Equal("fromNameResolver", cloned.ConnectionNameResolver); }
public async Task NameResolver() { Attr1 a1 = new Attr1 { Path = "x%appsetting%y-{k}" }; var nameResolver = new FakeNameResolver().Add("appsetting", "ABC"); var cloner = new AttributeCloner <Attr1>(a1, GetBindingContract("k"), nameResolver); // Get the attribute with %% resolved (happens at indexing time), but not {} (not resolved until runtime) var attrPre = cloner.GetNameResolvedAttribute(); Assert.Equal("xABCy-{k}", attrPre.Path); Dictionary <string, object> values = new Dictionary <string, object>() { { "k", "v" } }; var ctx = GetCtx(values); var attr2 = await cloner.ResolveFromBindingData(ctx); Assert.Equal("xABCy-v", attr2.Path); }
public void Validation_Direct_Early_Fail(string value, bool shouldSucceed) { ValidationOnlyAttribute attr = new ValidationOnlyAttribute { Value = value }; Dictionary <string, object> values = new Dictionary <string, object>() { { "x", "ignored" }, // ignored since not autoresolve }; var ctx = GetCtx(values); try { var cloner = new AttributeCloner <ValidationOnlyAttribute>(attr, GetBindingContract("name")); if (shouldSucceed) { // Success var attrResolved = cloner.ResolveFromBindings(values); // no autoresolve/appsetting, so the final value should be the same as the input value. Assert.Equal(value, attrResolved.Value); return; } Assert.False(true, "Validation should have failed"); } catch (InvalidOperationException e) { Assert.False(shouldSucceed); // Non-appsetting, so include the value in the message Assert.True(e.Message.Contains(value)); } }
public async Task InvokeStringMultipleResolvedProperties() { Attr2 attr = new Attr2("{p2}", "constant") { ResolvedProp1 = "{p1}" }; var cloner = new AttributeCloner <Attr2>(attr, GetBindingContract("p1", "p2")); Attr2 attrResolved = cloner.ResolveFromBindings(new Dictionary <string, object> { { "p1", "v1" }, { "p2", "v2" } }); Assert.Equal("v1", attrResolved.ResolvedProp1); Assert.Equal("v2", attrResolved.ResolvedProp2); Assert.Equal(attr.ConstantProp, attrResolved.ConstantProp); var invokeString = cloner.GetInvokeString(attrResolved); var attr2 = await cloner.ResolveFromInvokeString(invokeString); Assert.Equal(attrResolved.ResolvedProp1, attr2.ResolvedProp1); Assert.Equal(attrResolved.ResolvedProp2, attr2.ResolvedProp2); Assert.Equal(attrResolved.ConstantProp, attr2.ConstantProp); }
public async Task Easy() { Attr1 a1 = new Attr1 { Path = "{key1}-{key2}" }; Dictionary<string, object> values = new Dictionary<string, object>() { { "key1", "val1" }, { "key2", "val2" } }; var ctx = GetCtx(values); var cloner = new AttributeCloner<Attr1>(a1, GetBindingContract("key1", "key2")); var attr2 = await cloner.ResolveFromBindingDataAsync(ctx); Assert.Equal("val1-val2", attr2.Path); }
public async Task InvokeStringBlobAttribute() { foreach (var attr in new BlobAttribute[] { new BlobAttribute("container/{name}"), new BlobAttribute("container/constant", FileAccess.ReadWrite), new BlobAttribute("container/{name}", FileAccess.Write) }) { var cloner = new AttributeCloner<BlobAttribute>(attr, GetBindingContract("name")); BlobAttribute attr2 = await cloner.ResolveFromInvokeStringAsync("c/n"); Assert.Equal("c/n", attr2.BlobPath); Assert.Equal(attr.Access, attr2.Access); } }
public async Task InvokeString() { Attr1 a1 = new Attr1 { Path = "%test%" }; Assert.Null(a1 as IAttributeInvokeDescriptor<Attr1>); // Does not implement the interface var nameResolver = new FakeNameResolver(); nameResolver._dict["test"] = "ABC"; var cloner = new AttributeCloner<Attr1>(a1, EmptyContract, nameResolver); Attr1 attr2 = await cloner.ResolveFromInvokeStringAsync("xy"); Assert.Equal("xy", attr2.Path); }
public async Task Setting_Null() { Attr2 a2 = new Attr2(string.Empty, string.Empty); var cloner = new AttributeCloner<Attr2>(a2, EmptyContract, null); Attr2 a2Clone = await cloner.ResolveFromBindingDataAsync(GetCtx(null)); Assert.Null(a2Clone.ResolvedSetting); }
public async Task CloneNoDefaultCtorShortList() { // Use shorter parameter list. var a1 = new BlobAttribute("container/{name}.txt"); Dictionary<string, object> values = new Dictionary<string, object>() { { "name", "green" }, }; var ctx = GetCtx(values); var cloner = new AttributeCloner<BlobAttribute>(a1, GetBindingContract("name")); var attr2 = await cloner.ResolveFromBindingDataAsync(ctx); Assert.Equal("container/green.txt", attr2.BlobPath); Assert.Equal(a1.Access, attr2.Access); }
public void Setting() { Attr2 a2 = new Attr2(string.Empty, string.Empty) { ResolvedSetting = "appsetting" }; var nameResolver = new FakeNameResolver().Add("appsetting", "ABC"); var cloner = new AttributeCloner<Attr2>(a2, EmptyContract, nameResolver); var a2Cloned = cloner.GetNameResolvedAttribute(); Assert.Equal("ABC", a2Cloned.ResolvedSetting); }
public void GetPolicy_Throws_IfPolicyDoesNotImplementInterface() { PropertyInfo propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithInvalidPolicy)); InvalidOperationException ex = Assert.Throws <InvalidOperationException>(() => AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(propInfo)); Assert.Equal($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {nameof(AttributeWithResolutionPolicy.PropWithInvalidPolicy)} must derive from {typeof(IResolutionPolicy).Name}.", ex.Message); }
public async Task NameResolver() { Attr1 a1 = new Attr1 { Path = "x%appsetting%y-{k}" }; var nameResolver = new FakeNameResolver().Add("appsetting", "ABC"); var cloner = new AttributeCloner<Attr1>(a1, GetBindingContract("k"), nameResolver); // Get the attribute with %% resolved (happens at indexing time), but not {} (not resolved until runtime) var attrPre = cloner.GetNameResolvedAttribute(); Assert.Equal("xABCy-{k}", attrPre.Path); Dictionary<string, object> values = new Dictionary<string, object>() { { "k", "v" } }; var ctx = GetCtx(values); var attr2 = await cloner.ResolveFromBindingDataAsync(ctx); Assert.Equal("xABCy-v", attr2.Path); }
public async Task InvokeStringMultipleResolvedProperties() { Attr2 attr = new Attr2("{p2}", "constant") { ResolvedProp1 = "{p1}" }; var cloner = new AttributeCloner<Attr2>(attr, GetBindingContract("p1", "p2")); Attr2 attrResolved = cloner.ResolveFromBindings(new Dictionary<string, object> { { "p1", "v1" }, { "p2", "v2" }}); Assert.Equal("v1", attrResolved.ResolvedProp1); Assert.Equal("v2", attrResolved.ResolvedProp2); Assert.Equal(attr.ConstantProp, attrResolved.ConstantProp); var invokeString = cloner.GetInvokeString(attrResolved); var attr2 = await cloner.ResolveFromInvokeStringAsync(invokeString); Assert.Equal(attrResolved.ResolvedProp1, attr2.ResolvedProp1); Assert.Equal(attrResolved.ResolvedProp2, attr2.ResolvedProp2); Assert.Equal(attrResolved.ConstantProp, attr2.ConstantProp); }
public void GetPolicy_Throws_IfPolicyHasNoDefaultConstructor() { PropertyInfo propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithConstructorlessPolicy)); InvalidOperationException ex = Assert.Throws <InvalidOperationException>(() => AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(propInfo)); Assert.Equal($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {nameof(AttributeWithResolutionPolicy.PropWithConstructorlessPolicy)} must derive from {typeof(IResolutionPolicy).Name} and have a default constructor.", ex.Message); }