Add tests for IndexHtmlFileProvider, plus minor cleanups

This commit is contained in:
Steve Sanderson 2017-12-13 12:33:03 +00:00
parent affc66c24e
commit 39b64c1bc3
5 changed files with 148 additions and 18 deletions

View File

@ -12,12 +12,15 @@ namespace Microsoft.Blazor.Server.FrameworkFiles
{ {
public static IFileProvider Instantiate(string clientAssemblyPath) public static IFileProvider Instantiate(string clientAssemblyPath)
=> new CompositeFileProvider( => new CompositeFileProvider(
MonoStaticFileProvider.JsFiles, MonoStaticFileProvider.JsFiles, // /_framework/wasm/*, /framework/asmjs/*
BlazorBrowserFileProvider.Instance, BlazorBrowserFileProvider.Instance, // /_framework/blazor.js
new ReferencedAssemblyFileProvider( BinDirFileProvider(clientAssemblyPath)); // /_framework/_bin/*
private static IFileProvider BinDirFileProvider(string clientAssemblyPath)
=> new ReferencedAssemblyFileProvider(
Path.GetFileNameWithoutExtension(clientAssemblyPath), Path.GetFileNameWithoutExtension(clientAssemblyPath),
new ReferencedAssemblyResolver( new ReferencedAssemblyResolver(
MonoStaticFileProvider.BclFiles, MonoStaticFileProvider.BclFiles,
Path.GetDirectoryName(clientAssemblyPath)))); Path.GetDirectoryName(clientAssemblyPath)));
} }
} }

View File

@ -12,33 +12,27 @@ namespace Microsoft.Blazor.Server.WebRootFiles
{ {
internal class IndexHtmlFileProvider : InMemoryFileProvider internal class IndexHtmlFileProvider : InMemoryFileProvider
{ {
public IndexHtmlFileProvider(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles) public IndexHtmlFileProvider(string htmlTemplate, string assemblyName, IEnumerable<IFileInfo> binFiles)
: base(ComputeContents(clientWebRoot, assemblyName, binFiles)) : base(ComputeContents(htmlTemplate, assemblyName, binFiles))
{ {
} }
private static IEnumerable<(string, Stream)> ComputeContents(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles) private static IEnumerable<(string, Stream)> ComputeContents(string htmlTemplate, string assemblyName, IEnumerable<IFileInfo> binFiles)
{ {
var html = GetIndexHtmlContents(clientWebRoot, assemblyName, binFiles); if (htmlTemplate != null)
if (html != null)
{ {
var html = GetIndexHtmlContents(htmlTemplate, assemblyName, binFiles);
var htmlBytes = Encoding.UTF8.GetBytes(html); var htmlBytes = Encoding.UTF8.GetBytes(html);
var htmlStream = new MemoryStream(htmlBytes); var htmlStream = new MemoryStream(htmlBytes);
yield return ("/index.html", htmlStream); yield return ("/index.html", htmlStream);
} }
} }
private static string GetIndexHtmlContents(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles) private static string GetIndexHtmlContents(string htmlTemplate, string assemblyName, IEnumerable<IFileInfo> binFiles)
{ {
var indexHtmlPath = Path.Combine(clientWebRoot, "index.html");
if (!File.Exists(indexHtmlPath))
{
return null;
}
// TODO: Consider parsing the HTML properly so for example we don't insert into // TODO: Consider parsing the HTML properly so for example we don't insert into
// the wrong place if there was also '</body>' in a JavaScript string literal // the wrong place if there was also '</body>' in a JavaScript string literal
return File.ReadAllText(indexHtmlPath) return htmlTemplate
.Replace("</body>", CreateBootMarkup(assemblyName, binFiles) + "\n</body>"); .Replace("</body>", CreateBootMarkup(assemblyName, binFiles) + "\n</body>");
} }

View File

@ -3,6 +3,7 @@
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace Microsoft.Blazor.Server.WebRootFiles namespace Microsoft.Blazor.Server.WebRootFiles
{ {
@ -11,7 +12,14 @@ namespace Microsoft.Blazor.Server.WebRootFiles
public static IFileProvider Instantiate( public static IFileProvider Instantiate(
string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles) string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles)
=> new CompositeFileProvider( => new CompositeFileProvider(
new IndexHtmlFileProvider(clientWebRoot, assemblyName, binFiles), new IndexHtmlFileProvider(
ReadIndexHtmlFile(clientWebRoot), assemblyName, binFiles),
new PhysicalFileProvider(clientWebRoot)); new PhysicalFileProvider(clientWebRoot));
private static string ReadIndexHtmlFile(string clientWebRoot)
{
var path = Path.Combine(clientWebRoot, "index.html");
return File.Exists(path) ? File.ReadAllText(path) : null;
}
} }
} }

View File

@ -0,0 +1,124 @@
// 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 Microsoft.Blazor.Server.WebRootFiles;
using Microsoft.Extensions.FileProviders;
using System.IO;
using System.Linq;
using Xunit;
using System;
using AngleSharp.Parser.Html;
namespace Microsoft.Blazor.Server.Test
{
public class IndexHtmlFileProviderTest
{
[Fact]
public void SuppliesNoIndexHtmlFileGivenNoTemplate()
{
// Arrange
var instance = new IndexHtmlFileProvider(
null, "fakeassembly", Enumerable.Empty<IFileInfo>());
// Act
var file = instance.GetFileInfo("/index.html");
// Assert
Assert.False(file.Exists);
}
[Fact]
public void SuppliesIndexHtmlFileGivenTemplate()
{
// Arrange
var htmlTemplate = "test";
var instance = new IndexHtmlFileProvider(
htmlTemplate, "fakeassembly", Enumerable.Empty<IFileInfo>());
// Act
var file = instance.GetFileInfo("/index.html");
// Assert
Assert.True(file.Exists);
Assert.False(file.IsDirectory);
Assert.Equal("/index.html", file.PhysicalPath);
Assert.Equal("index.html", file.Name);
Assert.Equal(htmlTemplate, ReadString(file));
Assert.Equal(htmlTemplate.Length, file.Length);
}
[Fact]
public void RootDirectoryContainsOnlyIndexHtml()
{
// Arrange
var htmlTemplate = "test";
var instance = new IndexHtmlFileProvider(
htmlTemplate, "fakeassembly", Enumerable.Empty<IFileInfo>());
// Act
var directory = instance.GetDirectoryContents(string.Empty);
// Assert
Assert.True(directory.Exists);
Assert.Collection(directory,
item => Assert.Equal("/index.html", item.PhysicalPath));
}
[Fact]
public void InsertsScriptTagReferencingAssemblyAndDependencies()
{
// Arrange
var htmlTemplate = "<html><body>Hello</body></html>";
var dependencies = new IFileInfo[]
{
new TestFileInfo("System.Abc.dll"),
new TestFileInfo("MyApp.ClassLib.dll"),
};
var instance = new IndexHtmlFileProvider(
htmlTemplate, "MyApp.Entrypoint", dependencies);
// Act
var file = instance.GetFileInfo("/index.html");
var parsedHtml = new HtmlParser().Parse(ReadString(file));
var scriptElem = parsedHtml.Body.LastElementChild;
// Assert
Assert.Equal("script", scriptElem.TagName.ToLowerInvariant());
Assert.False(scriptElem.HasChildNodes);
Assert.Equal("/_framework/blazor.js", scriptElem.GetAttribute("src"));
Assert.Equal("MyApp.Entrypoint.dll", scriptElem.GetAttribute("main"));
Assert.Equal("System.Abc.dll,MyApp.ClassLib.dll", scriptElem.GetAttribute("references"));
}
private static string ReadString(IFileInfo file)
{
using (var stream = file.CreateReadStream())
using (var sr = new StreamReader(stream))
{
return sr.ReadToEnd();
}
}
class TestFileInfo : IFileInfo
{
public TestFileInfo(string physicalPath)
{
PhysicalPath = physicalPath;
}
public bool Exists => true;
public long Length => throw new NotImplementedException();
public string PhysicalPath { get; }
public string Name => Path.GetFileName(PhysicalPath);
public DateTimeOffset LastModified => throw new NotImplementedException();
public bool IsDirectory => false;
public Stream CreateReadStream() => throw new NotImplementedException();
}
}
}

View File

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="0.9.9" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />