Skip to content

Commit 308c97c

Browse files
author
Warren Buckley
authored
Merge pull request #40 from profcinders/feature/svg-tests
Add tests for the inline svg tag helper
2 parents 6d4d48b + 0693dde commit 308c97c

File tree

3 files changed

+217
-7
lines changed

3 files changed

+217
-7
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.AspNetCore.Razor.TagHelpers;
3+
using Microsoft.Extensions.FileProviders;
4+
using Microsoft.Extensions.Options;
5+
using Moq;
6+
using NUnit.Framework;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.IO;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
using Umbraco.Cms.Core.Configuration.Models;
13+
using Umbraco.Cms.Core.IO;
14+
using Umbraco.Cms.Core.Models.PublishedContent;
15+
using Umbraco.Cms.Core.Routing;
16+
17+
namespace Our.Umbraco.TagHelpers.Tests
18+
{
19+
public class InlineSvgTagHelperTests
20+
{
21+
private TagHelperContext _context = null!;
22+
private TagHelperOutput _output = null!;
23+
24+
[SetUp]
25+
public void Setup()
26+
{
27+
var attributes = new TagHelperAttributeList
28+
{
29+
{ "src", "test-src" },
30+
{ "media-item", "test-media" }
31+
};
32+
_context = new TagHelperContext(attributes, new Dictionary<object, object>(), "test");
33+
_output = new TagHelperOutput("umb-svg", attributes, (result, encoder) =>
34+
{
35+
var content = new DefaultTagHelperContent();
36+
content.SetContent("Something else");
37+
return Task.FromResult<TagHelperContent>(content);
38+
});
39+
}
40+
41+
[Test]
42+
public void NoOutputIfNoMediaOrFileSet()
43+
{
44+
var tagHelper = new InlineSvgTagHelper(null, null, null);
45+
46+
tagHelper.Process(_context, _output);
47+
48+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
49+
}
50+
51+
[Test]
52+
public void NoOutputIfBothMediaAndFileSet()
53+
{
54+
var umbContent = Mock.Of<IPublishedContent>(c => c.ContentType.ItemType == PublishedItemType.Media);
55+
var tagHelper = new InlineSvgTagHelper(null, null, null)
56+
{
57+
FileSource = "test.svg",
58+
MediaItem = umbContent
59+
};
60+
61+
tagHelper.Process(_context, _output);
62+
63+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
64+
}
65+
66+
[Test]
67+
public void NoOutputIfFileNotSvg()
68+
{
69+
var tagHelper = new InlineSvgTagHelper(null, null, null)
70+
{
71+
FileSource = "test.notsvg"
72+
};
73+
74+
tagHelper.Process(_context, _output);
75+
76+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
77+
}
78+
79+
[Test]
80+
public void NoOutputIfFileNotFound()
81+
{
82+
var fileProvider = new Mock<IFileProvider>();
83+
fileProvider.Setup(p => p.GetFileInfo(It.IsAny<string>())).Returns(Mock.Of<IFileInfo>(f => !f.Exists));
84+
var hostEnv = Mock.Of<IWebHostEnvironment>(e => e.WebRootFileProvider == fileProvider.Object);
85+
var tagHelper = new InlineSvgTagHelper(null, hostEnv, null)
86+
{
87+
FileSource = "test.svg"
88+
};
89+
90+
tagHelper.Process(_context, _output);
91+
92+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
93+
}
94+
95+
[Test]
96+
public void ExpectedOutputIfValidFile()
97+
{
98+
var fileProvider = new Mock<IFileProvider>();
99+
fileProvider.Setup(p => p.GetFileInfo(It.IsAny<string>())).Returns(Mock.Of<IFileInfo>(f => f.Exists && f.CreateReadStream() == new MemoryStream(Encoding.UTF8.GetBytes("test svg"))));
100+
var hostEnv = Mock.Of<IWebHostEnvironment>(e => e.WebRootFileProvider == fileProvider.Object);
101+
var tagHelper = new InlineSvgTagHelper(null, hostEnv, null)
102+
{
103+
FileSource = "test.svg"
104+
};
105+
106+
tagHelper.Process(_context, _output);
107+
108+
Assert.IsNull(_output?.TagName);
109+
Assert.AreEqual(_output.Content.GetContent(), "test svg");
110+
Assert.IsFalse(_output.Attributes.ContainsName("src"));
111+
Assert.IsFalse(_output.Attributes.ContainsName("media-item"));
112+
}
113+
114+
[Test]
115+
public void NoOutputIfMediaUrlNull()
116+
{
117+
var urlProvider = new Mock<IPublishedUrlProvider>();
118+
urlProvider.Setup(p => p.GetMediaUrl(It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns((string)null!);
119+
var tagHelper = new InlineSvgTagHelper(null, null, urlProvider.Object)
120+
{
121+
MediaItem = Mock.Of<IPublishedContent>(c => c.ContentType.ItemType == PublishedItemType.Media)
122+
};
123+
124+
tagHelper.Process(_context, _output);
125+
126+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
127+
}
128+
129+
[Test]
130+
public void NoOutputIfMediaNotSvg()
131+
{
132+
var umbContent = Mock.Of<IPublishedContent>(c => c.ContentType.ItemType == PublishedItemType.Media);
133+
var urlProvider = new Mock<IPublishedUrlProvider>();
134+
urlProvider.Setup(p => p.GetMediaUrl(umbContent, It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns("test.notsvg");
135+
var tagHelper = new InlineSvgTagHelper(null, null, urlProvider.Object)
136+
{
137+
MediaItem = umbContent
138+
};
139+
140+
tagHelper.Process(_context, _output);
141+
142+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
143+
}
144+
145+
[Test]
146+
public void NoOutputIfMediaNotFound()
147+
{
148+
var umbContent = Mock.Of<IPublishedContent>(c => c.ContentType.ItemType == PublishedItemType.Media);
149+
var urlProvider = new Mock<IPublishedUrlProvider>();
150+
urlProvider.Setup(p => p.GetMediaUrl(umbContent, It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns("test.svg");
151+
var fileSystem = Mock.Of<IFileSystem>(fs => !fs.FileExists(It.IsAny<string>()));
152+
var tagHelper = new InlineSvgTagHelper(
153+
new MediaFileManager(fileSystem, null, null, null, null, Mock.Of<IOptions<ContentSettings>>()),
154+
null,
155+
urlProvider.Object)
156+
{
157+
MediaItem = umbContent
158+
};
159+
160+
tagHelper.Process(_context, _output);
161+
162+
Assert.IsTrue(_output.Content.IsEmptyOrWhiteSpace);
163+
}
164+
165+
[Test]
166+
public void ExpectedOutputIfValidMedia()
167+
{
168+
var umbContent = Mock.Of<IPublishedContent>(c => c.ContentType.ItemType == PublishedItemType.Media);
169+
var urlProvider = new Mock<IPublishedUrlProvider>();
170+
urlProvider.Setup(p => p.GetMediaUrl(umbContent, It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns("test.svg");
171+
var fileSystem = Mock.Of<IFileSystem>(fs => fs.FileExists(It.IsAny<string>()) && fs.OpenFile(It.IsAny<string>()) == new MemoryStream(Encoding.UTF8.GetBytes("test svg")));
172+
var tagHelper = new InlineSvgTagHelper(
173+
new MediaFileManager(fileSystem, null, null, null, null, Mock.Of<IOptions<ContentSettings>>()),
174+
null,
175+
urlProvider.Object)
176+
{
177+
MediaItem = umbContent
178+
};
179+
180+
tagHelper.Process(_context, _output);
181+
182+
Assert.IsNull(_output?.TagName);
183+
Assert.AreEqual("test svg", _output.Content.GetContent());
184+
Assert.IsFalse(_output.Attributes.ContainsName("src"));
185+
Assert.IsFalse(_output.Attributes.ContainsName("media-item"));
186+
}
187+
188+
[Test]
189+
public void SanitizesJavascript()
190+
{
191+
var fileProvider = new Mock<IFileProvider>();
192+
fileProvider
193+
.Setup(p => p.GetFileInfo(It.IsAny<string>()))
194+
.Returns(Mock.Of<IFileInfo>(f => f.Exists && f.CreateReadStream() == new MemoryStream(Encoding.UTF8.GetBytes("<a xlink:href=\"javascript:alert('test');\">Click here</a><script attr=\"test\">test</script>end"))));
195+
var hostEnv = Mock.Of<IWebHostEnvironment>(e => e.WebRootFileProvider == fileProvider.Object);
196+
var tagHelper = new InlineSvgTagHelper(null, hostEnv, null)
197+
{
198+
FileSource = "test.svg"
199+
};
200+
201+
tagHelper.Process(_context, _output);
202+
203+
Assert.AreEqual("<a xlink:href=\"syntax:error:alert('test');\">Click here</a>end", _output.Content.GetContent());
204+
}
205+
}
206+
}

Our.Umbraco.TagHelpers.Tests/Our.Umbraco.TagHelpers.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
1111
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />
1212
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
13+
<PackageReference Include="Moq" Version="4.18.2" />
1314
<PackageReference Include="NUnit" Version="3.13.2" />
1415
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
1516
<PackageReference Include="coverlet.collector" Version="3.1.0">

Our.Umbraco.TagHelpers/InlineSvgTagHelper.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,27 @@
55
using System.Text.RegularExpressions;
66
using Umbraco.Cms.Core.IO;
77
using Umbraco.Cms.Core.Models.PublishedContent;
8+
using Umbraco.Cms.Core.Routing;
89
using Umbraco.Extensions;
910

1011
namespace Our.Umbraco.TagHelpers
1112
{
1213
/// <summary>
13-
/// This allows you to inline an SVG file into the DOM
14+
/// This allows you to inline an SVG file into the DOM
1415
/// from a file on disk or an Umbraco Media Item
1516
/// </summary>
1617
[HtmlTargetElement("our-svg")]
1718
public class InlineSvgTagHelper : TagHelper
1819
{
1920
private MediaFileManager _mediaFileManager;
2021
private IWebHostEnvironment _webHostEnvironment;
22+
private IPublishedUrlProvider _urlProvider;
2123

22-
public InlineSvgTagHelper(MediaFileManager mediaFileManager, IWebHostEnvironment webHostEnvironment)
24+
public InlineSvgTagHelper(MediaFileManager mediaFileManager, IWebHostEnvironment webHostEnvironment, IPublishedUrlProvider urlProvider)
2325
{
2426
_mediaFileManager = mediaFileManager;
2527
_webHostEnvironment = webHostEnvironment;
28+
_urlProvider = urlProvider;
2629
}
2730

2831
/// <summary>
@@ -59,8 +62,8 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
5962
{
6063
// Check Umbraco Media Item that is picked/used
6164
// has a file that uses a .svg file extension
62-
var mediaItemPath = MediaItem.Url();
63-
if(mediaItemPath.EndsWith(".svg", StringComparison.InvariantCultureIgnoreCase) == false)
65+
var mediaItemPath = MediaItem.Url(_urlProvider);
66+
if (mediaItemPath?.EndsWith(".svg", StringComparison.InvariantCultureIgnoreCase) != true)
6467
{
6568
output.SuppressOutput();
6669
return;
@@ -101,11 +104,11 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
101104
return;
102105
}
103106

104-
fileContents = File.ReadAllText(file.PhysicalPath);
107+
using var reader = new StreamReader(file.CreateReadStream());
108+
fileContents = reader.ReadToEnd();
105109
}
106110

107-
108-
// Sanatize SVG (Is there anything in Umbraco to reuse)
111+
// Sanitize SVG (Is there anything in Umbraco to reuse)
109112
// https://stackoverflow.com/questions/65247336/is-there-anyway-to-sanitize-svg-file-in-c-any-libraries-anything/65375485#65375485
110113
var cleanedFileContents = Regex.Replace(fileContents,
111114
@"<script.*?script>",

0 commit comments

Comments
 (0)