|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Rewrite.IISUrlRewrite;
using Microsoft.AspNetCore.Rewrite.UrlActions;
using Microsoft.AspNetCore.Rewrite.UrlMatches;
namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite;
public class FileParserTests
{
[Fact]
public void RuleParse_ParseTypicalRule()
{
// arrange
var xml = @"<rewrite>
<rules>
<rule name=""Rewrite to article.aspx"">
<match url = ""^article/([0-9]+)/([_0-9a-z-]+)"" />
<action type=""Rewrite"" url =""article.aspx?id={R:1}&title={R:2}"" />
</rule>
</rules>
</rewrite>";
var expected = new List<IISUrlRewriteRule>();
expected.Add(CreateTestRule(new ConditionCollection(),
url: "^article/([0-9]+)/([_0-9a-z-]+)",
name: "Rewrite to article.aspx",
actionType: ActionType.Rewrite,
pattern: "article.aspx?id={R:1}&title={R:2}"));
// act
var res = new UrlRewriteFileParser().Parse(new StringReader(xml), false);
// assert
AssertUrlRewriteRuleEquality(expected, res);
}
[Fact]
public void RuleParse_ParseSingleRuleWithSingleCondition()
{
// arrange
var xml = @"<rewrite>
<rules>
<rule name=""Rewrite to article.aspx"">
<match url = ""^article/([0-9]+)/([_0-9a-z-]+)"" />
<conditions>
<add input=""{HTTPS}"" pattern=""^OFF$"" />
</conditions>
<action type=""Rewrite"" url =""article.aspx?id={R:1}&title={R:2}"" />
</rule>
</rules>
</rewrite>";
var condList = new ConditionCollection();
condList.Add(new Condition(new InputParser().ParseInputString("{HTTPS}"), new RegexMatch(new Regex("^OFF$"), false)));
var expected = new List<IISUrlRewriteRule>();
expected.Add(CreateTestRule(condList,
url: "^article/([0-9]+)/([_0-9a-z-]+)",
name: "Rewrite to article.aspx",
actionType: ActionType.Rewrite,
pattern: "article.aspx?id={R:1}&title={R:2}"));
// act
var res = new UrlRewriteFileParser().Parse(new StringReader(xml), false);
// assert
AssertUrlRewriteRuleEquality(expected, res);
}
[Fact]
public void RuleParse_ParseMultipleRules()
{
// arrange
var xml = @"<rewrite>
<rules>
<rule name=""Rewrite to article.aspx"">
<match url = ""^article/([0-9]+)/([_0-9a-z-]+)"" />
<conditions>
<add input=""{HTTPS}"" pattern=""^OFF$"" />
</conditions>
<action type=""Rewrite"" url =""article.aspx?id={R:1}&title={R:2}"" />
</rule>
<rule name=""Rewrite to another article.aspx"">
<match url = ""^article/([0-9]+)/([_0-9a-z-]+)"" />
<conditions>
<add input=""{HTTPS}"" pattern=""^OFF$"" />
</conditions>
<action type=""Rewrite"" url =""article.aspx?id={R:1}&title={R:2}"" />
</rule>
</rules>
</rewrite>";
var condList = new ConditionCollection();
condList.Add(new Condition(new InputParser().ParseInputString("{HTTPS}"), new RegexMatch(new Regex("^OFF$"), false)));
var expected = new List<IISUrlRewriteRule>();
expected.Add(CreateTestRule(condList,
url: "^article/([0-9]+)/([_0-9a-z-]+)",
name: "Rewrite to article.aspx",
actionType: ActionType.Rewrite,
pattern: "article.aspx?id={R:1}&title={R:2}"));
expected.Add(CreateTestRule(condList,
url: "^article/([0-9]+)/([_0-9a-z-]+)",
name: "Rewrite to another article.aspx",
actionType: ActionType.Rewrite,
pattern: "article.aspx?id={R:1}&title={R:2}"));
// act
var res = new UrlRewriteFileParser().Parse(new StringReader(xml), false);
// assert
AssertUrlRewriteRuleEquality(expected, res);
}
[Fact]
public void Should_parse_global_rules()
{
// arrange
var xml = @"<rewrite>
<globalRules>
<rule name=""httpsOnly"" patternSyntax=""ECMAScript"" stopProcessing=""true"">
<match url="".*"" />
<conditions logicalGrouping=""MatchAll"" trackAllCaptures=""false"">
<add input=""{HTTPS}"" pattern=""off"" />
</conditions>
<action type=""Redirect"" url=""https://{HTTP_HOST}{REQUEST_URI}"" />
</rule>
</globalRules>
<rules>
<rule name=""Rewrite to article.aspx"">
<match url = ""^article/([0-9]+)/([_0-9a-z-]+)"" />
<action type=""Rewrite"" url =""article.aspx?id={R:1}&title={R:2}"" />
</rule>
</rules>
</rewrite>";
// act
var rules = new UrlRewriteFileParser().Parse(new StringReader(xml), false);
// assert
Assert.Equal(2, rules.Count);
Assert.True(rules[0].Global);
Assert.False(rules[1].Global);
}
[Fact]
public void Should_skip_empty_conditions()
{
// arrange
var xml = @"<rewrite>
<rules>
<rule name=""redirect-aspnet-mvc"" enabled=""true"" stopProcessing=""true"">
<match url=""^aspnet/Mvc"" />
<conditions logicalGrouping=""MatchAll"" trackAllCaptures=""false"" />
<action type=""Redirect"" url=""https://github.com/dotnet/aspnetcore"" />
</rule>
</rules>
</rewrite>";
// act
var rules = new UrlRewriteFileParser().Parse(new StringReader(xml), false);
// assert
Assert.Null(rules[0].Conditions);
}
// Creates a rule with appropriate default values of the url rewrite rule.
private static IISUrlRewriteRule CreateTestRule(ConditionCollection conditions,
string name = "",
bool enabled = true,
PatternSyntax patternSyntax = PatternSyntax.ECMAScript,
bool stopProcessing = false,
string url = "",
bool ignoreCase = true,
bool negate = false,
ActionType actionType = ActionType.None,
string pattern = "",
bool appendQueryString = false,
bool rewrittenUrl = false,
bool global = false,
UriMatchPart uriMatchPart = UriMatchPart.Path,
RedirectType redirectType = RedirectType.Permanent
)
{
return new IISUrlRewriteRule(
name,
new RegexMatch(new Regex("^OFF$"), negate),
conditions,
new RewriteAction(RuleResult.ContinueRules, new InputParser().ParseInputString(url, uriMatchPart), queryStringAppend: false),
global);
}
// TODO make rules comparable?
private static void AssertUrlRewriteRuleEquality(IList<IISUrlRewriteRule> actual, IList<IISUrlRewriteRule> expected)
{
Assert.Equal(actual.Count, expected.Count);
for (var i = 0; i < actual.Count; i++)
{
var r1 = actual[i];
var r2 = expected[i];
Assert.Equal(r1.Name, r2.Name);
if (r1.Conditions == null)
{
Assert.Equal(0, r2.Conditions.Count);
}
else if (r2.Conditions == null)
{
Assert.Equal(0, r1.Conditions.Count);
}
else
{
Assert.Equal(r1.Conditions.Count, r2.Conditions.Count);
for (var j = 0; j < r1.Conditions.Count; j++)
{
var c1 = r1.Conditions[j];
var c2 = r2.Conditions[j];
Assert.Equal(c1.Input.PatternSegments.Count, c2.Input.PatternSegments.Count);
}
}
Assert.Equal(r1.Action.GetType(), r2.Action.GetType());
Assert.Equal(r1.InitialMatch.GetType(), r2.InitialMatch.GetType());
}
}
}
|