Fixup XUnit warnings when running MVC tests (#9823)

This commit is contained in:
Pranav K 2019-04-29 09:32:48 -07:00 committed by GitHub
parent 33a4937d38
commit 2570126b27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 488 additions and 225 deletions

View File

@ -3,7 +3,6 @@
using System;
using System.IO;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
@ -20,73 +19,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
public class RazorPageCreateModelExpressionTest
{
public static TheoryData IdentityExpressions
{
get
{
return new TheoryData<Func<IdentityRazorPage, ModelExpression>, string>
{
// m => m
{ page => page.CreateModelExpression1(), string.Empty },
// m => Model
{ page => page.CreateModelExpression2(), string.Empty },
};
}
}
public static TheoryData NotQuiteIdentityExpressions
{
get
{
return new TheoryData<Func<NotQuiteIdentityRazorPage, ModelExpression>, string, Type>
{
// m => m.Model
{ page => page.CreateModelExpression1(), "Model", typeof(RecursiveModel) },
// m => ViewData.Model
{ page => page.CreateModelExpression2(), "ViewData.Model", typeof(RecursiveModel) },
// m => ViewContext.ViewData.Model
// This property has type object because ViewData is not exposed as ViewDataDictionary<TModel>.
{ page => page.CreateModelExpression3(), "ViewContext.ViewData.Model", typeof(object) },
};
}
}
public static TheoryData<Expression<Func<RazorPageCreateModelExpressionModel, int>>, string> IntExpressions
{
get
{
var somethingElse = 23;
return new TheoryData<Expression<Func<RazorPageCreateModelExpressionModel, int>>, string>
{
{ model => somethingElse, "somethingElse" },
{ model => model.Id, "Id" },
{ model => model.SubModel.Id, "SubModel.Id" },
{ model => model.SubModel.SubSubModel.Id, "SubModel.SubSubModel.Id" },
};
}
}
public static TheoryData<Expression<Func<RazorPageCreateModelExpressionModel, string>>, string> StringExpressions
{
get
{
var somethingElse = "This is something else";
return new TheoryData<Expression<Func<RazorPageCreateModelExpressionModel, string>>, string>
{
{ model => somethingElse, "somethingElse" },
{ model => model.Name, "Name" },
{ model => model.SubModel.Name, "SubModel.Name" },
{ model => model.SubModel.SubSubModel.Name, "SubModel.SubSubModel.Name" },
};
}
}
[Theory]
[MemberData(nameof(IdentityExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_IdentityExpressions(
Func<IdentityRazorPage, ModelExpression> createModelExpression,
string expectedName)
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IdentityExpressions_ForModelGivesM()
{
// m => m
// Arrange
var viewContext = CreateViewContext();
var modelExplorer = viewContext.ViewData.ModelExplorer.GetExplorerForProperty(
@ -100,22 +36,78 @@ namespace Microsoft.AspNetCore.Mvc.Razor
var page = CreateIdentityPage(viewContext);
// Act
var modelExpression = createModelExpression(page);
var modelExpression = page.CreateModelExpression1();
// Assert
Assert.NotNull(modelExpression);
Assert.Equal(expectedName, modelExpression.Name);
Assert.Empty(modelExpression.Name);
Assert.Same(modelExplorer, modelExpression.ModelExplorer);
}
[Theory]
[MemberData(nameof(NotQuiteIdentityExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_NotQuiteIdentityExpressions(
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IdentityExpressions_ForModelGivesModel()
{
// m => m.Model
// Arrange
var viewContext = CreateViewContext();
var modelExplorer = viewContext.ViewData.ModelExplorer.GetExplorerForProperty(
nameof(RazorPageCreateModelExpressionModel.Name));
var viewData = new ViewDataDictionary<string>(viewContext.ViewData)
{
ModelExplorer = modelExplorer,
};
viewContext.ViewData = viewData;
var page = CreateIdentityPage(viewContext);
// Act
var modelExpression = page.CreateModelExpression2();
// Assert
Assert.NotNull(modelExpression);
Assert.Empty(modelExpression.Name);
Assert.Same(modelExplorer, modelExpression.ModelExplorer);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_NotQuiteIdentityExpressions_ForModelGivesMDotModel()
{
// m => m.Model
// Arrange
var expectedName = "Model";
var expectedType = typeof(RecursiveModel);
CreateModelExpression_NotQuiteIdentityExpressions(page => page.CreateModelExpression1(), expectedName, expectedType);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_NotQuiteIdentityExpressions_ForModelGivesViewDataDotModel()
{
// m => ViewData.Model
// Arrange
var expectedName = "ViewData.Model";
var expectedType = typeof(RecursiveModel);
CreateModelExpression_NotQuiteIdentityExpressions(page => page.CreateModelExpression2(), expectedName, expectedType);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_NotQuiteIdentityExpressions_ForModelGivesViewContextDotViewDataDotModel()
{
// m => ViewContext.ViewData.Model
// Arrange
var expectedName = "ViewContext.ViewData.Model";
// This property has type object because ViewData is not exposed as ViewDataDictionary<TModel>.
var expectedType = typeof(object);
CreateModelExpression_NotQuiteIdentityExpressions(page => page.CreateModelExpression3(), expectedName, expectedType);
}
private static void CreateModelExpression_NotQuiteIdentityExpressions(
Func<NotQuiteIdentityRazorPage, ModelExpression> createModelExpression,
string expectedName,
Type expectedType)
{
// Arrange
var viewContext = CreateViewContext();
var viewData = new ViewDataDictionary<RecursiveModel>(viewContext.ViewData);
viewContext.ViewData = viewData;
@ -136,38 +128,144 @@ namespace Microsoft.AspNetCore.Mvc.Razor
Assert.Equal(expectedType, modelExpression.Metadata.ModelType);
}
[Theory]
[MemberData(nameof(IntExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions(
Expression<Func<RazorPageCreateModelExpressionModel, int>> expression,
string expectedName)
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions_ForModelGivesSomethingElse()
{
// Arrange
var expected = "somethingElse";
var somethingElse = 23;
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, expression);
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => somethingElse);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(int), result.Metadata.ModelType);
Assert.Equal(expectedName, result.Name);
Assert.Equal(expected, result.Name);
}
[Theory]
[MemberData(nameof(StringExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_StringExpressions(
Expression<Func<RazorPageCreateModelExpressionModel, string>> expression,
string expectedName)
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions_ForModelGivesId()
{
// Arrange
var expected = "Id";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, expression);
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.Id);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(int), result.Metadata.ModelType);
Assert.Equal(expected, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions_ForModelGivesSubModelId()
{
// Arrange
var expected = "SubModel.Id";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.SubModel.Id);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(int), result.Metadata.ModelType);
Assert.Equal(expected, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions_ForModelGivesSubSubModelId()
{
// Arrange
var expected = "SubModel.SubSubModel.Id";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.SubModel.SubSubModel.Id);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(int), result.Metadata.ModelType);
Assert.Equal(expected, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_StringExpressions_ForModelGivesSomethingElse()
{
// Arrange
var somethingElse = "This is something else";
var expectedName = "somethingElse";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => somethingElse);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(string), result.Metadata.ModelType);
Assert.Equal(expectedName, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_StringExpressions_ForModelGivesName()
{
// Arrange
var expectedName = "Name";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.Name);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(string), result.Metadata.ModelType);
Assert.Equal(expectedName, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_StringExpressions_ForModelGivesSubmodelName()
{
// Arrange
var expectedName = "SubModel.SubSubModel.Name";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.SubModel.SubSubModel.Name);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Metadata);
Assert.Equal(typeof(string), result.Metadata.ModelType);
Assert.Equal(expectedName, result.Name);
}
[Fact]
public void CreateModelExpression_ReturnsExpectedMetadata_StringExpressions_ForModelGivesSubSubmodelName()
{
// Arrange
var expectedName = "SubModel.Name";
var viewContext = CreateViewContext();
var page = CreatePage(viewContext);
// Act
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, model => model.SubModel.Name);
// Assert
Assert.NotNull(result);

View File

@ -140,24 +140,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
ex.Message);
}
public static TheoryData<HtmlEncoder> HtmlEncoderData
{
get
{
return new TheoryData<HtmlEncoder>
{
HtmlEncoder.Default,
NullHtmlEncoder.Default,
new HtmlTestEncoder(),
};
}
}
[Theory]
[MemberData(nameof(HtmlEncoderData))]
public async Task StartTagHelperWritingScope_SetsHtmlEncoder(HtmlEncoder encoder)
[Fact]
public async Task StartTagHelperWritingScope_SetsHtmlEncoder()
{
// Arrange
var encoder = Mock.Of<HtmlEncoder>();
var page = CreatePage(v =>
{
v.StartTagHelperWritingScope(encoder);
@ -1176,53 +1163,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor
get
{
// attributeValues, expectedValue
return new TheoryData<Tuple<string, int, object, int, bool>[], string>
return new TheoryData<string, int, object, int, bool, string>
{
{
new []
{
Tuple.Create(string.Empty, 9, (object)"Hello", 9, true),
},
"Hello"
string.Empty, 9, (object)"Hello", 9, true, "Hello"
},
{
new []
{
Tuple.Create(" ", 9, (object)"Hello", 10, true)
},
" Hello"
" ", 9, (object)"Hello", 10, true, " Hello"
},
{
new []
{
Tuple.Create(" ", 9, (object)null, 10, false)
},
string.Empty
" ", 9, (object)null, 10, false, string.Empty
},
{
new []
{
Tuple.Create(" ", 9, (object)false, 10, false)
},
" HtmlEncode[[False]]"
},
{
new []
{
Tuple.Create(" ", 9, (object)true, 11, false),
Tuple.Create(" ", 9, (object)"abcd", 17, true)
},
" HtmlEncode[[True]] abcd"
},
{
new []
{
Tuple.Create(string.Empty, 9, (object)"prefix", 9, true),
Tuple.Create(" ", 15, (object)null, 17, false),
Tuple.Create(" ", 21, (object)"suffix", 22, false),
},
"prefix HtmlEncode[[suffix]]"
" ", 9, (object)false, 10, false, " HtmlEncode[[False]]"
},
};
}
@ -1231,7 +1185,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
[Theory]
[MemberData(nameof(AddHtmlAttributeValues_ValueData))]
public void AddHtmlAttributeValues_AddsToHtmlAttributesAsExpected(
Tuple<string, int, object, int, bool>[] attributeValues,
string prefix,
int prefixOffset,
object value,
int valueOffset,
bool isLiteral,
string expectedValue)
{
// Arrange
@ -1246,6 +1204,94 @@ namespace Microsoft.AspNetCore.Mvc.Razor
startTagHelperWritingScope: _ => { },
endTagHelperWritingScope: () => new DefaultTagHelperContent());
// Act
page.BeginAddHtmlAttributeValues(executionContext, "someattr", 1, HtmlAttributeValueStyle.SingleQuotes);
page.AddHtmlAttributeValue(prefix, prefixOffset, value, valueOffset, 0, isLiteral);
page.EndAddHtmlAttributeValues(executionContext);
// Assert
var output = executionContext.Output;
var htmlAttribute = Assert.Single(output.Attributes);
Assert.Equal("someattr", htmlAttribute.Name, StringComparer.Ordinal);
var htmlContent = Assert.IsAssignableFrom<IHtmlContent>(htmlAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
Assert.Equal(HtmlAttributeValueStyle.SingleQuotes, htmlAttribute.ValueStyle);
var context = executionContext.Context;
var allAttribute = Assert.Single(context.AllAttributes);
Assert.Equal("someattr", allAttribute.Name, StringComparer.Ordinal);
htmlContent = Assert.IsAssignableFrom<IHtmlContent>(allAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
Assert.Equal(HtmlAttributeValueStyle.SingleQuotes, allAttribute.ValueStyle);
}
[Fact]
public void AddHtmlAttributeValues_TwoAttributeValues_AddsToHtmlAttributesAsExpected()
{
// Arrange
var expectedValue = " HtmlEncode[[True]] abcd";
var attributeValues = new[]
{
Tuple.Create(" ", 9, (object)true, 11, false),
Tuple.Create(" ", 9, (object)"abcd", 17, true)
};
var page = CreatePage(p => { });
page.HtmlEncoder = new HtmlTestEncoder();
var executionContext = new TagHelperExecutionContext(
"p",
tagMode: TagMode.StartTagAndEndTag,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
startTagHelperWritingScope: _ => { },
endTagHelperWritingScope: () => new DefaultTagHelperContent());
// Act
page.BeginAddHtmlAttributeValues(executionContext, "someattr", attributeValues.Length, HtmlAttributeValueStyle.SingleQuotes);
foreach (var value in attributeValues)
{
page.AddHtmlAttributeValue(value.Item1, value.Item2, value.Item3, value.Item4, 0, value.Item5);
}
page.EndAddHtmlAttributeValues(executionContext);
// Assert
var output = executionContext.Output;
var htmlAttribute = Assert.Single(output.Attributes);
Assert.Equal("someattr", htmlAttribute.Name, StringComparer.Ordinal);
var htmlContent = Assert.IsAssignableFrom<IHtmlContent>(htmlAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
Assert.Equal(HtmlAttributeValueStyle.SingleQuotes, htmlAttribute.ValueStyle);
var context = executionContext.Context;
var allAttribute = Assert.Single(context.AllAttributes);
Assert.Equal("someattr", allAttribute.Name, StringComparer.Ordinal);
htmlContent = Assert.IsAssignableFrom<IHtmlContent>(allAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
Assert.Equal(HtmlAttributeValueStyle.SingleQuotes, allAttribute.ValueStyle);
}
[Fact]
public void AddHtmlAttributeValues_ThreeAttributeValues_AddsToHtmlAttributesAsExpected()
{
// Arrange
var expectedValue = "prefix HtmlEncode[[suffix]]";
var attributeValues = new[]
{
Tuple.Create(string.Empty, 9, (object)"prefix", 9, true),
Tuple.Create(" ", 15, (object)null, 17, false),
Tuple.Create(" ", 21, (object)"suffix", 22, false),
};
var page = CreatePage(p => { });
page.HtmlEncoder = new HtmlTestEncoder();
var executionContext = new TagHelperExecutionContext(
"p",
tagMode: TagMode.StartTagAndEndTag,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: () => Task.FromResult(result: true),
startTagHelperWritingScope: _ => { },
endTagHelperWritingScope: () => new DefaultTagHelperContent());
// Act
page.BeginAddHtmlAttributeValues(executionContext, "someattr", attributeValues.Length, HtmlAttributeValueStyle.SingleQuotes);
foreach (var value in attributeValues)
@ -1342,50 +1388,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor
get
{
// AttributeValues, ExpectedOutput
return new TheoryData<Tuple<string, int, object, int, bool>[], string>
return new TheoryData<string, int, object, int, bool, string>
{
{
new[]
{
Tuple.Create(string.Empty, 9, (object)true, 9, false),
},
"someattr=HtmlEncode[[someattr]]"
string.Empty, 9, (object)true, 9, false, "someattr=HtmlEncode[[someattr]]"
},
{
new[]
{
Tuple.Create(string.Empty, 9, (object)false, 9, false),
},
string.Empty
string.Empty, 9, (object)false, 9, false, string.Empty
},
{
new[]
{
Tuple.Create(string.Empty, 9, (object)null, 9, false),
},
string.Empty
string.Empty, 9, (object)null, 9, false, string.Empty
},
{
new[]
{
Tuple.Create(" ", 9, (object)false, 11, false),
},
"someattr= HtmlEncode[[False]]"
" ", 9, (object)false, 11, false, "someattr= HtmlEncode[[False]]"
},
{
new[]
{
Tuple.Create(" ", 9, (object)null, 11, false),
},
"someattr="
},
{
new[]
{
Tuple.Create(" ", 9, (object)true, 11, false),
Tuple.Create(" ", 15, (object)"abcd", 17, true),
},
"someattr= HtmlEncode[[True]] abcd"
" ", 9, (object)null, 11, false, "someattr="
},
};
}
@ -1394,10 +1412,47 @@ namespace Microsoft.AspNetCore.Mvc.Razor
[Theory]
[MemberData(nameof(WriteAttributeData))]
public void WriteAttribute_UsesSpecifiedWriter_WritesAsExpected(
Tuple<string, int, object, int, bool>[] attributeValues,
string prefix,
int prefixOffset,
object value,
int valueOffset,
bool isLiteral,
string expectedOutput)
{
// Arrange
var page = CreatePage(p => { });
page.HtmlEncoder = new HtmlTestEncoder();
var writer = new StringWriter();
var suffix = string.Empty;
// Act
page.PushWriter(writer);
page.BeginWriteAttribute("someattr", "someattr=", 0, suffix, 0, 1);
page.WriteAttributeValue(
prefix,
prefixOffset,
value,
valueOffset,
value?.ToString().Length ?? 0,
isLiteral);
page.EndWriteAttribute();
page.PopWriter();
// Assert
Assert.Equal(expectedOutput, writer.ToString());
}
[Fact]
public void WriteAttribute_MultipleValues_UsesSpecifiedWriter_WritesAsExpected()
{
// Arrange
var attributeValues = new[]
{
Tuple.Create(" ", 9, (object)true, 11, false),
Tuple.Create(" ", 15, (object)"abcd", 17, true),
};
var expectedOutput = "someattr= HtmlEncode[[True]] abcd";
var page = CreatePage(p => { });
page.HtmlEncoder = new HtmlTestEncoder();
var writer = new StringWriter();

View File

@ -52,32 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
public static IEnumerable<object[]> ViewLocationExpanderTestData
{
get
{
yield return new object[]
{
_controllerTestContext,
new[]
{
"/Views/{1}/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
}
};
yield return new object[]
{
_areaTestContext,
new[]
{
"/Areas/{2}/Views/{1}/{0}.cshtml",
"/Areas/{2}/Views/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
}
};
}
}
[Theory]
[InlineData(null)]
@ -681,13 +656,85 @@ namespace Microsoft.AspNetCore.Mvc.Razor
Assert.Same(areaPage2, view4.RazorPage);
}
[Theory]
[MemberData(nameof(ViewLocationExpanderTestData))]
public void FindView_UsesViewLocationExpandersToLocateViews(
IDictionary<string, object> routeValues,
IEnumerable<string> expectedSeeds)
[Fact]
public void FindView_UsesViewLocationExpandersToLocateViews()
{
// Arrange
var routeValues = _controllerTestContext;
var expectedSeeds = new[]
{
"/Views/{1}/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
};
var pageFactory = new Mock<IRazorPageFactoryProvider>();
pageFactory
.Setup(p => p.CreateFactory("test-string/bar.cshtml"))
.Returns(GetPageFactoryResult(() => Mock.Of<IRazorPage>()))
.Verifiable();
var expander1Result = new[] { "some-seed" };
var expander1 = new Mock<IViewLocationExpander>();
expander1
.Setup(e => e.PopulateValues(It.IsAny<ViewLocationExpanderContext>()))
.Callback((ViewLocationExpanderContext c) =>
{
Assert.NotNull(c.ActionContext);
c.Values["expander-key"] = expander1.ToString();
})
.Verifiable();
expander1
.Setup(e => e.ExpandViewLocations(
It.IsAny<ViewLocationExpanderContext>(),
It.IsAny<IEnumerable<string>>()))
.Callback((ViewLocationExpanderContext c, IEnumerable<string> seeds) =>
{
Assert.NotNull(c.ActionContext);
Assert.Equal(expectedSeeds, seeds);
})
.Returns(expander1Result)
.Verifiable();
var expander2 = new Mock<IViewLocationExpander>();
expander2
.Setup(e => e.ExpandViewLocations(
It.IsAny<ViewLocationExpanderContext>(),
It.IsAny<IEnumerable<string>>()))
.Callback((ViewLocationExpanderContext c, IEnumerable<string> seeds) =>
{
Assert.Equal(expander1Result, seeds);
})
.Returns(new[] { "test-string/{1}.cshtml" })
.Verifiable();
var viewEngine = CreateViewEngine(
pageFactory.Object,
new[] { expander1.Object, expander2.Object });
var context = GetActionContext(routeValues);
// Act
var result = viewEngine.FindView(context, "test-view", isMainPage: true);
// Assert
Assert.True(result.Success);
Assert.IsAssignableFrom<IView>(result.View);
pageFactory.Verify();
expander1.Verify();
expander2.Verify();
}
[Fact]
public void FindView_UsesViewLocationExpandersToLocateViews_ForAreas()
{
// Arrange
var routeValues = _areaTestContext;
var expectedSeeds = new[]
{
"/Areas/{2}/Views/{1}/{0}.cshtml",
"/Areas/{2}/Views/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
};
var pageFactory = new Mock<IRazorPageFactoryProvider>();
pageFactory
.Setup(p => p.CreateFactory("test-string/bar.cshtml"))
@ -1092,13 +1139,76 @@ namespace Microsoft.AspNetCore.Mvc.Razor
"pageName");
}
[Theory]
[MemberData(nameof(ViewLocationExpanderTestData))]
public void FindPage_UsesViewLocationExpander_ToExpandPaths(
IDictionary<string, object> routeValues,
IEnumerable<string> expectedSeeds)
[Fact]
public void FindPage_UsesViewLocationExpander_ToExpandPaths()
{
// Arrange
var routeValues = _controllerTestContext;
var expectedSeeds = new[]
{
"/Views/{1}/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
};
var page = Mock.Of<IRazorPage>();
var pageFactory = new Mock<IRazorPageFactoryProvider>();
pageFactory
.Setup(p => p.CreateFactory("expanded-path/bar-layout"))
.Returns(GetPageFactoryResult(() => page))
.Verifiable();
var expander = new Mock<IViewLocationExpander>();
expander
.Setup(e => e.PopulateValues(It.IsAny<ViewLocationExpanderContext>()))
.Callback((ViewLocationExpanderContext c) =>
{
Assert.NotNull(c.ActionContext);
c.Values["expander-key"] = expander.ToString();
})
.Verifiable();
expander
.Setup(e => e.ExpandViewLocations(
It.IsAny<ViewLocationExpanderContext>(),
It.IsAny<IEnumerable<string>>()))
.Returns((ViewLocationExpanderContext c, IEnumerable<string> seeds) =>
{
Assert.NotNull(c.ActionContext);
Assert.Equal(expectedSeeds, seeds);
Assert.Equal(expander.ToString(), c.Values["expander-key"]);
return new[] { "expanded-path/bar-{0}" };
})
.Verifiable();
var viewEngine = CreateViewEngine(
pageFactory.Object,
new[] { expander.Object });
var context = GetActionContext(routeValues);
// Act
var result = viewEngine.FindPage(context, "layout");
// Assert
Assert.Equal("layout", result.Name);
Assert.Same(page, result.Page);
Assert.Null(result.SearchedLocations);
pageFactory.Verify();
expander.Verify();
}
[Fact]
public void FindPage_UsesViewLocationExpander_ToExpandPaths_ForAreas()
{
// Arrange
var routeValues = _areaTestContext;
var expectedSeeds = new[]
{
"/Areas/{2}/Views/{1}/{0}.cshtml",
"/Areas/{2}/Views/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml"
};
var page = Mock.Of<IRazorPage>();
var pageFactory = new Mock<IRazorPageFactoryProvider>();
pageFactory

View File

@ -108,12 +108,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
get
{
// url, expectedHref
return new TheoryData<HtmlString, string>
return new TheoryData<string, string>
{
{ new HtmlString("~/home/index.html"), "HtmlEncode[[/approot/]]home/index.html" },
{ new HtmlString(" ~/home/index.html"), "HtmlEncode[[/approot/]]home/index.html" },
{ "~/home/index.html", "HtmlEncode[[/approot/]]home/index.html" },
{ " ~/home/index.html", "HtmlEncode[[/approot/]]home/index.html" },
{
new HtmlString("~/home/index.html ~/secondValue/index.html"),
"~/home/index.html ~/secondValue/index.html",
"HtmlEncode[[/approot/]]home/index.html ~/secondValue/index.html"
},
};
@ -122,14 +122,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
[Theory]
[MemberData(nameof(ResolvableUrlHtmlStringData))]
public void Process_ResolvesTildeSlashValues_InHtmlString(object url, string expectedHref)
public void Process_ResolvesTildeSlashValues_InHtmlString(string url, string expectedHref)
{
// Arrange
var tagHelperOutput = new TagHelperOutput(
tagName: "a",
attributes: new TagHelperAttributeList
{
{ "href", url }
{ "href", new HtmlString(url) }
},
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(null));
var urlHelperMock = new Mock<IUrlHelper>();
@ -221,27 +221,27 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
get
{
// url
return new TheoryData<HtmlString>
return new TheoryData<string>
{
{ new HtmlString("/home/index.html") },
{ new HtmlString("~ /home/index.html") },
{ new HtmlString("/home/index.html ~/second/wontresolve.html") },
{ new HtmlString("~\\home\\index.html") },
{ new HtmlString("~\\/home/index.html") },
{ "/home/index.html" },
{ "~ /home/index.html" },
{ "/home/index.html ~/second/wontresolve.html" },
{ "~\\home\\index.html" },
{ "~\\/home/index.html" },
};
}
}
[Theory]
[MemberData(nameof(UnresolvableUrlHtmlStringData))]
public void Process_DoesNotResolveNonTildeSlashValues_InHtmlString(HtmlString url)
public void Process_DoesNotResolveNonTildeSlashValues_InHtmlString(string url)
{
// Arrange
var tagHelperOutput = new TagHelperOutput(
tagName: "a",
attributes: new TagHelperAttributeList
{
{ "href", url }
{ "href", new HtmlString(url) }
},
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(null));
var urlHelperMock = new Mock<IUrlHelper>();