Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/WebOptimizer.Core/Taghelpers/LinkInlineHrefTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;

namespace WebOptimizer.Taghelpers
Expand Down Expand Up @@ -92,11 +93,12 @@ private async Task<string> GetFileContentAsync(string route)
}

string cleanRoute = route.TrimStart('~');
string file = HostingEnvironment.WebRootFileProvider.GetFileInfo(cleanRoute).PhysicalPath;
IFileInfo file = HostingEnvironment.WebRootFileProvider.GetFileInfo(cleanRoute);

if (File.Exists(file))
if (file.Exists)
{
using (StreamReader reader = File.OpenText(file))
using (Stream stream = file.CreateReadStream())
using (StreamReader reader = new(stream))
{
content = await reader.ReadToEndAsync();
AddToCache(cacheKey, content, HostingEnvironment.WebRootFileProvider, cleanRoute);
Expand Down
8 changes: 5 additions & 3 deletions src/WebOptimizer.Core/Taghelpers/ScriptInlineSrcTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;

namespace WebOptimizer.Taghelpers
Expand Down Expand Up @@ -83,11 +84,12 @@ protected async Task<string> GetFileContentAsync(string route)
}

string cleanRoute = route.TrimStart('~');
string file = HostingEnvironment.WebRootFileProvider.GetFileInfo(cleanRoute).PhysicalPath;
IFileInfo file = HostingEnvironment.WebRootFileProvider.GetFileInfo(cleanRoute);

if (File.Exists(file))
if (file.Exists)
{
using (StreamReader reader = File.OpenText(file))
using (Stream stream = file.CreateReadStream())
using (StreamReader reader = new(stream))
{
content = await reader.ReadToEndAsync();
AddToCache(cacheKey, content, HostingEnvironment.WebRootFileProvider, cleanRoute);
Expand Down
26 changes: 26 additions & 0 deletions test/WebOptimizer.Core.Test/Mocks/MockChangeToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Microsoft.Extensions.Primitives;

namespace WebOptimizer.Core.Test.Mocks
{
public class MockChangeToken : IChangeToken
{
public bool ActiveChangeCallbacks => false;

public bool HasChanged => false;

public IDisposable RegisterChangeCallback(Action<object> callback, object state)
{
return NoopDisposable.Instance;
}

private class NoopDisposable : IDisposable
{
public static readonly NoopDisposable Instance = new();

public void Dispose()
{
}
}
}
}
27 changes: 27 additions & 0 deletions test/WebOptimizer.Core.Test/Mocks/MockDirectoryContents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using Microsoft.Extensions.FileProviders;

namespace WebOptimizer.Core.Test.Mocks
{
public class MockDirectoryContents : IDirectoryContents
{
private readonly IEnumerable<IFileInfo> _files;

public MockDirectoryContents(IEnumerable<IFileInfo> files)
{
_files = files;
}

public bool Exists => true;

public IEnumerator<IFileInfo> GetEnumerator()
{
return _files.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _files.GetEnumerator();
}
}
}
24 changes: 21 additions & 3 deletions test/WebOptimizer.Core.Test/Mocks/MockFileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,42 @@ internal class MockFileInfo : IFileInfo
{
private readonly byte[] _data;

public MockFileInfo(string name, DateTimeOffset lastModified, byte[] data)
public MockFileInfo(string fileName, DateTimeOffset lastModified, byte[] data)
{
_data = data;
Name = name;
Name = fileName;
LastModified = lastModified;
}

private MockFileInfo(string directoryName, DateTimeOffset lastModified, IList<MockFileInfo> files = null)
{
_data = null;
Name = directoryName;
LastModified = lastModified;
IsDirectory = true;
Files = files;
}

/// <summary>
/// Creates a new instance of <see cref="MockFileInfo"/> representing a directory.
/// </summary>
public static MockFileInfo CreateDirectory(string directoryName, DateTimeOffset lastModified, IList<MockFileInfo> files)
{
return new MockFileInfo(directoryName, lastModified, files);
}

public Stream CreateReadStream()
{
return new MemoryStream(_data, false);
}

public bool Exists => true;
public bool IsDirectory => false;
public bool IsDirectory { get; }
public DateTimeOffset LastModified { get; }
public long Length => _data.Length;
public string Name { get; }
public string PhysicalPath => null;
public IList<MockFileInfo> Files { get; }
}

}
79 changes: 79 additions & 0 deletions test/WebOptimizer.Core.Test/Mocks/MockFileProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;

namespace WebOptimizer.Core.Test.Mocks
{
// grabbed the logic from https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.TagHelpers/test/GlobbingUrlBuilderTest.cs
// and made it recursive
internal class MockFileProvider : IFileProvider
{
private readonly MockChangeToken _changeToken = new();
private readonly Dictionary<string, MockFileInfo> _files;
private readonly Dictionary<string, MockDirectoryContents> _directories;

private MockFileProvider(Dictionary<string, MockFileInfo> files, Dictionary<string, MockDirectoryContents> directories)
{
_files = files;
_directories = directories;
}

public static IFileProvider Create(MockFileInfo rootNode)
{
if (rootNode.Files == null || !rootNode.Files.Any())
{
throw new ArgumentException($"{nameof(rootNode)} must have children.", nameof(rootNode));
}

Dictionary<string, MockFileInfo> files = [];
Dictionary<string, MockDirectoryContents> directories = [];

var stack = new Stack<(MockFileInfo fileInfo, string directoryPath)>();
stack.Push((rootNode, string.Empty));

while (stack.Count > 0)
{
var (fileInfo, directoryPath) = stack.Pop();

if (fileInfo.IsDirectory)
{
var children = fileInfo.Files;

var fullPath = string.IsNullOrEmpty(directoryPath) ? fileInfo.Name : directoryPath + "/" + fileInfo.Name;

directories[fullPath] = new MockDirectoryContents(children);

foreach (var child in children)
{
stack.Push((child, fullPath));
}
}
else
{
var fullPath = string.IsNullOrEmpty(directoryPath) ? fileInfo.Name : directoryPath + "/" + fileInfo.Name;
files[fullPath] = fileInfo;
files["/" + fullPath] = fileInfo;
}
}

return new MockFileProvider(files, directories);
}

public IFileInfo GetFileInfo(string subpath)
{
return _files.TryGetValue(subpath, out var fileInfo) ? fileInfo : new NotFoundFileInfo(subpath);
}

public IDirectoryContents GetDirectoryContents(string subpath)
{
return _directories.TryGetValue(subpath, out var directoryContents) ? directoryContents : new NotFoundDirectoryContents();
}

public IChangeToken Watch(string filter)
{
return _changeToken;
}
}
}
Loading