Merge the source code for Microsoft.Extensions.WebEncoders

\n\nCommit migrated from ca683f396d
This commit is contained in:
Nate McMaster 2018-11-09 17:13:41 -08:00
commit d3a479cd5c
10 changed files with 1126 additions and 0 deletions

View File

@ -0,0 +1,83 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text.Encodings.Web;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.WebEncoders;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods for setting up web encoding services in an <see cref="IServiceCollection" />.
/// </summary>
public static class EncoderServiceCollectionExtensions
{
/// <summary>
/// Adds <see cref="HtmlEncoder"/>, <see cref="JavaScriptEncoder"/> and <see cref="UrlEncoder"/>
/// to the specified <paramref name="services" />.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddWebEncoders(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.AddOptions();
// Register the default encoders
// We want to call the 'Default' property getters lazily since they perform static caching
services.TryAddSingleton(
CreateFactory(() => HtmlEncoder.Default, settings => HtmlEncoder.Create(settings)));
services.TryAddSingleton(
CreateFactory(() => JavaScriptEncoder.Default, settings => JavaScriptEncoder.Create(settings)));
services.TryAddSingleton(
CreateFactory(() => UrlEncoder.Default, settings => UrlEncoder.Create(settings)));
return services;
}
/// <summary>
/// Adds <see cref="HtmlEncoder"/>, <see cref="JavaScriptEncoder"/> and <see cref="UrlEncoder"/>
/// to the specified <paramref name="services" />.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/>.</param>
/// <param name="setupAction">An <see cref="Action{WebEncoderOptions}"/> to configure the provided <see cref="WebEncoderOptions"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddWebEncoders(this IServiceCollection services, Action<WebEncoderOptions> setupAction)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (setupAction == null)
{
throw new ArgumentNullException(nameof(setupAction));
}
services.AddWebEncoders();
services.Configure(setupAction);
return services;
}
private static Func<IServiceProvider, TService> CreateFactory<TService>(
Func<TService> defaultFactory,
Func<TextEncoderSettings, TService> customSettingsFactory)
{
return serviceProvider =>
{
var settings = serviceProvider
?.GetService<IOptions<WebEncoderOptions>>()
?.Value
?.TextEncoderSettings;
return (settings != null) ? customSettingsFactory(settings) : defaultFactory();
};
}
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Contains registration and configuration APIs to add the core framework encoders to a dependency injection container.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore</PackageTags>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<Reference Include="Microsoft.Extensions.Options" />
<Reference Include="System.Text.Encodings.Web" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,104 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Text.Encodings.Web;
namespace Microsoft.Extensions.WebEncoders.Testing
{
/// <summary>
/// Encoder used for unit testing.
/// </summary>
public sealed class HtmlTestEncoder : HtmlEncoder
{
public override int MaxOutputCharactersPerInputCharacter
{
get { return 1; }
}
public override string Encode(string value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (value.Length == 0)
{
return string.Empty;
}
return $"HtmlEncode[[{value}]]";
}
public override void Encode(TextWriter output, char[] value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("HtmlEncode[[");
output.Write(value, startIndex, characterCount);
output.Write("]]");
}
public override void Encode(TextWriter output, string value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("HtmlEncode[[");
output.Write(value.Substring(startIndex, characterCount));
output.Write("]]");
}
public override bool WillEncode(int unicodeScalar)
{
return false;
}
public override unsafe int FindFirstCharacterToEncode(char* text, int textLength)
{
return -1;
}
public override unsafe bool TryEncodeUnicodeScalar(
int unicodeScalar,
char* buffer,
int bufferLength,
out int numberOfCharactersWritten)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
numberOfCharactersWritten = 0;
return false;
}
}
}

View File

@ -0,0 +1,104 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Text.Encodings.Web;
namespace Microsoft.Extensions.WebEncoders.Testing
{
/// <summary>
/// Encoder used for unit testing.
/// </summary>
public class JavaScriptTestEncoder : JavaScriptEncoder
{
public override int MaxOutputCharactersPerInputCharacter
{
get { return 1; }
}
public override string Encode(string value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (value.Length == 0)
{
return string.Empty;
}
return $"JavaScriptEncode[[{value}]]";
}
public override void Encode(TextWriter output, char[] value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("JavaScriptEncode[[");
output.Write(value, startIndex, characterCount);
output.Write("]]");
}
public override void Encode(TextWriter output, string value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("JavaScriptEncode[[");
output.Write(value.Substring(startIndex, characterCount));
output.Write("]]");
}
public override bool WillEncode(int unicodeScalar)
{
return false;
}
public override unsafe int FindFirstCharacterToEncode(char* text, int textLength)
{
return -1;
}
public override unsafe bool TryEncodeUnicodeScalar(
int unicodeScalar,
char* buffer,
int bufferLength,
out int numberOfCharactersWritten)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
numberOfCharactersWritten = 0;
return false;
}
}
}

View File

@ -0,0 +1,104 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Text.Encodings.Web;
namespace Microsoft.Extensions.WebEncoders.Testing
{
/// <summary>
/// Encoder used for unit testing.
/// </summary>
public class UrlTestEncoder : UrlEncoder
{
public override int MaxOutputCharactersPerInputCharacter
{
get { return 1; }
}
public override string Encode(string value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (value.Length == 0)
{
return string.Empty;
}
return $"UrlEncode[[{value}]]";
}
public override void Encode(TextWriter output, char[] value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("UrlEncode[[");
output.Write(value, startIndex, characterCount);
output.Write("]]");
}
public override void Encode(TextWriter output, string value, int startIndex, int characterCount)
{
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (characterCount == 0)
{
return;
}
output.Write("UrlEncode[[");
output.Write(value.Substring(startIndex, characterCount));
output.Write("]]");
}
public override bool WillEncode(int unicodeScalar)
{
return false;
}
public override unsafe int FindFirstCharacterToEncode(char* text, int textLength)
{
return -1;
}
public override unsafe bool TryEncodeUnicodeScalar(
int unicodeScalar,
char* buffer,
int bufferLength,
out int numberOfCharactersWritten)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
numberOfCharactersWritten = 0;
return false;
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text.Encodings.Web;
namespace Microsoft.Extensions.WebEncoders
{
/// <summary>
/// Specifies options common to all three encoders (HtmlEncode, JavaScriptEncode, UrlEncode).
/// </summary>
public sealed class WebEncoderOptions
{
/// <summary>
/// Specifies which code points are allowed to be represented unescaped by the encoders.
/// </summary>
/// <remarks>
/// If this property is null, then the encoders will use their default allow lists.
/// </remarks>
public TextEncoderSettings TextEncoderSettings { get; set; }
}
}

View File

@ -0,0 +1,564 @@
{
"AssemblyIdentity": "Microsoft.Extensions.WebEncoders, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.Extensions.WebEncoders.WebEncoderOptions",
"Visibility": "Public",
"Kind": "Class",
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_TextEncoderSettings",
"Parameters": [],
"ReturnType": "System.Text.Encodings.Web.TextEncoderSettings",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_TextEncoderSettings",
"Parameters": [
{
"Name": "value",
"Type": "System.Text.Encodings.Web.TextEncoderSettings"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.WebEncoders.Testing.HtmlTestEncoder",
"Visibility": "Public",
"Kind": "Class",
"Sealed": true,
"BaseType": "System.Text.Encodings.Web.HtmlEncoder",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_MaxOutputCharactersPerInputCharacter",
"Parameters": [],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.String",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.Char[]"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.String"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "WillEncode",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "FindFirstCharacterToEncode",
"Parameters": [
{
"Name": "text",
"Type": "System.Char*"
},
{
"Name": "textLength",
"Type": "System.Int32"
}
],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "TryEncodeUnicodeScalar",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
},
{
"Name": "buffer",
"Type": "System.Char*"
},
{
"Name": "bufferLength",
"Type": "System.Int32"
},
{
"Name": "numberOfCharactersWritten",
"Type": "System.Int32",
"Direction": "Out"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.WebEncoders.Testing.JavaScriptTestEncoder",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "System.Text.Encodings.Web.JavaScriptEncoder",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_MaxOutputCharactersPerInputCharacter",
"Parameters": [],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.String",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.Char[]"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.String"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "WillEncode",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "FindFirstCharacterToEncode",
"Parameters": [
{
"Name": "text",
"Type": "System.Char*"
},
{
"Name": "textLength",
"Type": "System.Int32"
}
],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "TryEncodeUnicodeScalar",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
},
{
"Name": "buffer",
"Type": "System.Char*"
},
{
"Name": "bufferLength",
"Type": "System.Int32"
},
{
"Name": "numberOfCharactersWritten",
"Type": "System.Int32",
"Direction": "Out"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.WebEncoders.Testing.UrlTestEncoder",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "System.Text.Encodings.Web.UrlEncoder",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_MaxOutputCharactersPerInputCharacter",
"Parameters": [],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.String",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.Char[]"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Encode",
"Parameters": [
{
"Name": "output",
"Type": "System.IO.TextWriter"
},
{
"Name": "value",
"Type": "System.String"
},
{
"Name": "startIndex",
"Type": "System.Int32"
},
{
"Name": "characterCount",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "WillEncode",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "FindFirstCharacterToEncode",
"Parameters": [
{
"Name": "text",
"Type": "System.Char*"
},
{
"Name": "textLength",
"Type": "System.Int32"
}
],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "TryEncodeUnicodeScalar",
"Parameters": [
{
"Name": "unicodeScalar",
"Type": "System.Int32"
},
{
"Name": "buffer",
"Type": "System.Char*"
},
{
"Name": "bufferLength",
"Type": "System.Int32"
},
{
"Name": "numberOfCharactersWritten",
"Type": "System.Int32",
"Direction": "Out"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.DependencyInjection.EncoderServiceCollectionExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddWebEncoders",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
}
],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "AddWebEncoders",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
},
{
"Name": "setupAction",
"Type": "System.Action<Microsoft.Extensions.WebEncoders.WebEncoderOptions>"
}
],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}

View File

@ -0,0 +1,90 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text.Encodings.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.WebEncoders.Testing;
using Xunit;
namespace Microsoft.Extensions.WebEncoders
{
public class EncoderServiceCollectionExtensionsTests
{
[Fact]
public void AddWebEncoders_WithoutOptions_RegistersDefaultEncoders()
{
// Arrange
var serviceCollection = new ServiceCollection();
// Act
serviceCollection.AddWebEncoders();
// Assert
var serviceProvider = serviceCollection.BuildServiceProvider();
Assert.Same(HtmlEncoder.Default, serviceProvider.GetRequiredService<HtmlEncoder>()); // default encoder
Assert.Same(HtmlEncoder.Default, serviceProvider.GetRequiredService<HtmlEncoder>()); // as singleton instance
Assert.Same(JavaScriptEncoder.Default, serviceProvider.GetRequiredService<JavaScriptEncoder>()); // default encoder
Assert.Same(JavaScriptEncoder.Default, serviceProvider.GetRequiredService<JavaScriptEncoder>()); // as singleton instance
Assert.Same(UrlEncoder.Default, serviceProvider.GetRequiredService<UrlEncoder>()); // default encoder
Assert.Same(UrlEncoder.Default, serviceProvider.GetRequiredService<UrlEncoder>()); // as singleton instance
}
[Fact]
public void AddWebEncoders_WithOptions_RegistersEncodersWithCustomCodeFilter()
{
// Arrange
var serviceCollection = new ServiceCollection();
// Act
serviceCollection.AddWebEncoders(options =>
{
options.TextEncoderSettings = new TextEncoderSettings();
options.TextEncoderSettings.AllowCharacters("ace".ToCharArray()); // only these three chars are allowed
});
// Assert
var serviceProvider = serviceCollection.BuildServiceProvider();
var htmlEncoder = serviceProvider.GetRequiredService<HtmlEncoder>();
Assert.Equal("a&#x62;c&#x64;e", htmlEncoder.Encode("abcde"));
Assert.Same(htmlEncoder, serviceProvider.GetRequiredService<HtmlEncoder>()); // as singleton instance
var javaScriptEncoder = serviceProvider.GetRequiredService<JavaScriptEncoder>();
Assert.Equal(@"a\u0062c\u0064e", javaScriptEncoder.Encode("abcde"));
Assert.Same(javaScriptEncoder, serviceProvider.GetRequiredService<JavaScriptEncoder>()); // as singleton instance
var urlEncoder = serviceProvider.GetRequiredService<UrlEncoder>();
Assert.Equal("a%62c%64e", urlEncoder.Encode("abcde"));
Assert.Same(urlEncoder, serviceProvider.GetRequiredService<UrlEncoder>()); // as singleton instance
}
[Fact]
public void AddWebEncoders_DoesNotOverrideExistingRegisteredEncoders()
{
// Arrange
var serviceCollection = new ServiceCollection();
// Act
serviceCollection.AddSingleton<HtmlEncoder, HtmlTestEncoder>();
serviceCollection.AddSingleton<JavaScriptEncoder, JavaScriptTestEncoder>();
// we don't register an existing URL encoder
serviceCollection.AddWebEncoders(options =>
{
options.TextEncoderSettings = new TextEncoderSettings();
options.TextEncoderSettings.AllowCharacters("ace".ToCharArray()); // only these three chars are allowed
});
// Assert
var serviceProvider = serviceCollection.BuildServiceProvider();
var htmlEncoder = serviceProvider.GetRequiredService<HtmlEncoder>();
Assert.Equal("HtmlEncode[[abcde]]", htmlEncoder.Encode("abcde"));
var javaScriptEncoder = serviceProvider.GetRequiredService<JavaScriptEncoder>();
Assert.Equal("JavaScriptEncode[[abcde]]", javaScriptEncoder.Encode("abcde"));
var urlEncoder = serviceProvider.GetRequiredService<UrlEncoder>();
Assert.Equal("a%62c%64e", urlEncoder.Encode("abcde"));
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Xunit;
namespace Microsoft.Extensions.WebEncoders.Testing
{
public class HtmlTestEncoderTest
{
[Theory]
[InlineData("", "")]
[InlineData("abcd", "HtmlEncode[[abcd]]")]
[InlineData("<<''\"\">>", "HtmlEncode[[<<''\"\">>]]")]
public void StringEncode_EncodesAsExpected(string input, string expectedOutput)
{
// Arrange
var encoder = new HtmlTestEncoder();
// Act
var output = encoder.Encode(input);
// Assert
Assert.Equal(expectedOutput, output);
}
}
}

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.WebEncoders" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
</Project>