From 303a41202737d3ea7cb41bba695eebf4acfdbd43 Mon Sep 17 00:00:00 2001 From: James South Date: Mon, 6 Apr 2015 14:52:07 +0100 Subject: [PATCH] Adding final rewrites plus tests Former-commit-id: 74c8486327c0f1e786b2e2a1b91ba83f7ccbaeb0 Former-commit-id: d915f5acb0d97a854d2ffc5cd0e718ac29caf626 Former-commit-id: 3f83d99d82797da08ba61312e39f7e1e2e2ef605 --- .../ImageProcessor.Web.UnitTests.csproj | 2 + .../QueryParamParserUnitTests.cs | 158 ++++++++++++++++++ .../RegularExpressionUnitTests.cs | 52 +----- .../ExtendedColorTypeConverter.cs | 4 +- .../HttpModules/ImageProcessingModule.cs | 30 ++-- src/ImageProcessor.Web/Processors/Resize.cs | 14 +- src/ImageProcessor/Imaging/ResizeLayer.cs | 10 +- src/ImageProcessor/Properties/AssemblyInfo.cs | 1 + src/TestWebsites/MVC/Views/Home/Bmp.cshtml | 2 +- src/TestWebsites/MVC/Views/Home/Gif.cshtml | 6 +- src/TestWebsites/MVC/Views/Home/Png.cshtml | 5 +- src/TestWebsites/MVC/Views/Home/Png8.cshtml | 2 +- src/TestWebsites/MVC/Views/Home/Tiff.cshtml | 2 +- src/TestWebsites/MVC/Views/Home/WebP.cshtml | 2 +- 14 files changed, 210 insertions(+), 80 deletions(-) create mode 100644 src/ImageProcessor.Web.UnitTests/QueryParamParserUnitTests.cs diff --git a/src/ImageProcessor.Web.UnitTests/ImageProcessor.Web.UnitTests.csproj b/src/ImageProcessor.Web.UnitTests/ImageProcessor.Web.UnitTests.csproj index d89506079..de05afdfe 100644 --- a/src/ImageProcessor.Web.UnitTests/ImageProcessor.Web.UnitTests.csproj +++ b/src/ImageProcessor.Web.UnitTests/ImageProcessor.Web.UnitTests.csproj @@ -44,6 +44,7 @@ + @@ -57,6 +58,7 @@ + diff --git a/src/ImageProcessor.Web.UnitTests/QueryParamParserUnitTests.cs b/src/ImageProcessor.Web.UnitTests/QueryParamParserUnitTests.cs new file mode 100644 index 000000000..c0514770a --- /dev/null +++ b/src/ImageProcessor.Web.UnitTests/QueryParamParserUnitTests.cs @@ -0,0 +1,158 @@ +namespace ImageProcessor.Web.UnitTests +{ + using System.Collections.Specialized; + using System.Drawing; + using System.Web; + + using ImageProcessor.Imaging; + using ImageProcessor.Web.Helpers; + + using NUnit.Framework; + + /// + /// The query param parser unit tests. + /// + [TestFixture] + public class QueryParamParserUnitTests + { + [Test] + public void SingleParamOutputNotNull() + { + const string Param = "query=1"; + NameValueCollection query = HttpUtility.ParseQueryString(Param); + string result = QueryParamParser.Instance.ParseValue(query["query"]); + Assert.IsNotNull(result); + } + + [Test] + [TestCase("foo=4.5&foo=2.3", "foo")] + [TestCase("query=1.5&query=2.5", "query")] + public void MultipleParamOutputNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + float[] result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("", "entropycrop")] + [TestCase("entropycrop=0", "entropycrop")] + [TestCase("entropycrop=128", "entropycrop")] + public void IntNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + int result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("", "entropycrop")] + [TestCase("entropycrop=0", "entropycrop")] + [TestCase("entropycrop=128", "entropycrop")] + [TestCase("entropycrop=256", "entropycrop")] + public void ByteNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + byte result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("", "greyscale")] + [TestCase("greyscale=false", "greyscale")] + [TestCase("greyscale=true", "greyscale")] + public void BoolNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + bool result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + //[TestCase("", "rect")] + [TestCase("rect=0,0,100,100", "rect")] + public void RectangleNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + Rectangle result = QueryParamParser.Instance.ParseValue(query[parameter]); + + Assert.IsNotNull(result); + } + + [TestCase("", "size")] + [TestCase("size=1,1", "size")] + [TestCase("size=1", "size")] + public void SizeNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + Size result = QueryParamParser.Instance.ParseValue(query[parameter]); + + Assert.IsNotNull(result); + } + + [TestCase("", "point")] + [TestCase("point=1,1", "point")] + public void PointNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + Point result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("point=1.5,1.5", "point")] + public void PointFNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + PointF result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("resizemode=foo", "resizemode")] + [TestCase("resizemode=Max", "resizemode")] + [TestCase("resizemode=max", "resizemode")] + public void EnumNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + ResizeMode result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("", "resizemode")] + [TestCase("resizemode=foo", "resizemode")] + public void EnumIsDefault(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + ResizeMode result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.AreEqual(result, ResizeMode.Pad); + } + + [TestCase("resizemode=Max", "resizemode", ResizeMode.Max)] + [TestCase("resizemode=max", "resizemode", ResizeMode.Max)] + [TestCase("resizemode=crop", "resizemode", ResizeMode.Crop)] + public void EnumMatch(string queryString, string parameter, ResizeMode expected) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + ResizeMode result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.AreEqual(result, expected); + } + + [TestCase("color=white", "color")] + public void ColorNotNull(string queryString, string parameter) + { + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + Color result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.IsNotNull(result); + } + + [TestCase("color=255,255,255,255", "color")] + [TestCase("color=#fff", "color")] + [TestCase("color=#ffffff", "color")] + [TestCase("color=fff", "color")] + [TestCase("color=ffffff", "color")] + [TestCase("color=white", "color")] + [TestCase("color=White", "color")] + public void ColorMatch(string queryString, string parameter) + { + Color expected = Color.White; + NameValueCollection query = HttpUtility.ParseQueryString(queryString); + Color result = QueryParamParser.Instance.ParseValue(query[parameter]); + Assert.AreEqual(result.ToArgb(), expected.ToArgb()); + } + } +} diff --git a/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs b/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs index 7df015d63..ec1fe19ec 100644 --- a/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs +++ b/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs @@ -37,9 +37,7 @@ namespace ImageProcessor.Web.UnitTests /// [Test] [TestCase("alpha=66", 66)] - [TestCase("alpha=-66", 66)] - [TestCase("alpha=101", 1)] - [TestCase("alpha=-101", 1)] + [TestCase("alpha=101", 100)] [TestCase("alpha=000053", 53)] public void TestAlphaRegex(string input, int expected) { @@ -63,7 +61,7 @@ namespace ImageProcessor.Web.UnitTests [TestCase("brightness=56", 56)] [TestCase("brightness=84", 84)] [TestCase("brightness=66", 66)] - [TestCase("brightness=101", 1)] + [TestCase("brightness=101", 100)] [TestCase("brightness=00001", 1)] [TestCase("brightness=-50", -50)] [TestCase("brightness=0", 0)] @@ -89,7 +87,7 @@ namespace ImageProcessor.Web.UnitTests [TestCase("contrast=56", 56)] [TestCase("contrast=84", 84)] [TestCase("contrast=66", 66)] - [TestCase("contrast=101", 1)] + [TestCase("contrast=101", 100)] [TestCase("contrast=00001", 1)] [TestCase("contrast=-50", -50)] [TestCase("contrast=0", 0)] @@ -207,9 +205,8 @@ namespace ImageProcessor.Web.UnitTests [TestCase("quality=56", 56)] [TestCase("quality=84", 84)] [TestCase("quality=66", 66)] - [TestCase("quality=101", 1)] + [TestCase("quality=101", 100)] [TestCase("quality=00001", 1)] - [TestCase("quality=-50", 50)] [TestCase("quality=0", 0)] public void TestQualityRegex(string input, int expected) { @@ -291,7 +288,7 @@ namespace ImageProcessor.Web.UnitTests [TestCase("rotate=0", 0F)] [TestCase("rotate=270", 270F)] [TestCase("rotate=-270", -270F)] - [TestCase("rotate=angle-28", 28F)] + [TestCase("rotate=28", 28F)] public void TestRotateRegex(string input, float expected) { Processors.Rotate rotate = new Processors.Rotate(); @@ -314,10 +311,7 @@ namespace ImageProcessor.Web.UnitTests "roundedcorners=30", new RoundedCornerLayer(30) }, { - "roundedcorners=radius-26|tl-true|tr-false|bl-true|br-false", new RoundedCornerLayer(26, true, false, true, false) - }, - { - "roundedcorners=26,tl=true,tr=false,bl=true,br=false", new RoundedCornerLayer(26, true, false, true, false) + "roundedcorners=26&tl=true&tr=false&bl=true&br=false", new RoundedCornerLayer(26, true, false, true, false) } }; @@ -343,7 +337,7 @@ namespace ImageProcessor.Web.UnitTests [TestCase("saturation=56", 56)] [TestCase("saturation=84", 84)] [TestCase("saturation=66", 66)] - [TestCase("saturation=101", 1)] + [TestCase("saturation=101", 100)] [TestCase("saturation=00001", 1)] [TestCase("saturation=-50", -50)] [TestCase("saturation=0", 0)] @@ -383,7 +377,7 @@ namespace ImageProcessor.Web.UnitTests { tint.MatchRegexIndex(item.Key); Color result = tint.Processor.DynamicParameter; - Assert.AreEqual(item.Value, result); + Assert.AreEqual(item.Value.ToArgb(), result.ToArgb()); } } @@ -433,35 +427,7 @@ namespace ImageProcessor.Web.UnitTests Dictionary data = new Dictionary { { - "watermark=text-watermark goodness,color-fff,size-36,style-italic,opacity-80,position-30,150,shadow-true,font-arial", - new TextLayer - { - Text = "watermark goodness", - FontColor = ColorTranslator.FromHtml("#" + "ffffff"), - FontSize = 36, - Style = FontStyle.Italic, - Opacity = 80, - Position = new Point(30, 150), - DropShadow = true, - FontFamily = new FontFamily("arial") - } - }, - { - "watermark=watermark goodness&color=fff&fontsize=36&fontstyle=italic&fontopacity=80&textposition=30,150&textshadow=true&fontfamily=arial", - new TextLayer - { - Text = "watermark goodness", - FontColor = ColorTranslator.FromHtml("#" + "ffffff"), - FontSize = 36, - Style = FontStyle.Italic, - Opacity = 80, - Position = new Point(30, 150), - DropShadow = true, - FontFamily = new FontFamily("arial") - } - }, - { - "watermark=watermark goodness&color=fff&fontsize=36&fontstyle=italic&fontopacity=80&watermark.position=30,150&textshadow=true&fontfamily=arial", + "watermark=watermark goodness&color=fff&fontsize=36&fontstyle=italic&fontopacity=80&textposition=30,150&dropshadow=true&fontfamily=arial", new TextLayer { Text = "watermark goodness", diff --git a/src/ImageProcessor.Web/Helpers/QuerystringParser/ExtendedColorTypeConverter.cs b/src/ImageProcessor.Web/Helpers/QuerystringParser/ExtendedColorTypeConverter.cs index 612c93d37..ffb1e6960 100644 --- a/src/ImageProcessor.Web/Helpers/QuerystringParser/ExtendedColorTypeConverter.cs +++ b/src/ImageProcessor.Web/Helpers/QuerystringParser/ExtendedColorTypeConverter.cs @@ -93,10 +93,10 @@ namespace ImageProcessor.Web.Helpers if (components.Length == 4) { return Color.FromArgb( + Convert.ToInt32(components[3]), Convert.ToInt32(components[0]), Convert.ToInt32(components[1]), - Convert.ToInt32(components[2]), - Convert.ToInt32(components[3])); + Convert.ToInt32(components[2])); } return Color.FromArgb( diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index 04f808b0b..990ab2eb5 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -315,31 +315,29 @@ namespace ImageProcessor.Web.HttpModules if (isLegacy && hasMultiParams) { // We need to split the querystring to get the actual values we want. - string multiQuery = request.QueryString.ToString(); + string[] paths = url.Split('?'); - if (!string.IsNullOrWhiteSpace(multiQuery)) - { - // UrlDecode seems to mess up in some circumstance. - if (multiQuery.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1) - { - multiQuery = multiQuery.Replace(":/", "://"); - } - - string[] paths = multiQuery.Split('?'); + //if (!string.IsNullOrWhiteSpace(multiQuery)) + //{ + //// UrlDecode seems to mess up in some circumstance. + //if (multiQuery.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1) + //{ + // multiQuery = multiQuery.Replace(":/", "://"); + //} - requestPath = paths[0]; + requestPath = paths[1]; // Handle extension-less urls. - if (paths.Length > 2) + if (paths.Length > 3) { - queryString = paths[2]; - urlParameters = paths[1]; + queryString = paths[3]; + urlParameters = paths[2]; } else if (paths.Length > 1) { - queryString = paths[1]; + queryString = paths[2]; } - } + //} } else { diff --git a/src/ImageProcessor.Web/Processors/Resize.cs b/src/ImageProcessor.Web/Processors/Resize.cs index 5e9b228b8..e04c64e07 100644 --- a/src/ImageProcessor.Web/Processors/Resize.cs +++ b/src/ImageProcessor.Web/Processors/Resize.cs @@ -83,13 +83,15 @@ namespace ImageProcessor.Web.Processors ResizeMode mode = QueryParamParser.Instance.ParseValue(queryCollection["mode"]); AnchorPosition position = QueryParamParser.Instance.ParseValue(queryCollection["anchor"]); bool upscale = queryCollection["upscale"] == null || QueryParamParser.Instance.ParseValue(queryCollection["upscale"]); - float[] center = QueryParamParser.Instance.ParseValue(queryCollection["center"]); + float[] center = queryCollection["center"] != null + ? QueryParamParser.Instance.ParseValue(queryCollection["center"]) : + new float[] { }; ResizeLayer resizeLayer = new ResizeLayer(size) { - ResizeMode = mode, - AnchorPosition = position, - Upscale = upscale, + ResizeMode = mode, + AnchorPosition = position, + Upscale = upscale, CenterCoordinates = center }; @@ -101,7 +103,7 @@ namespace ImageProcessor.Web.Processors ((ImageProcessor.Processors.Resize)this.Processor).RestrictedSizes = this.ParseRestrictions( restrictions); } - + return this.SortOrder; } @@ -137,7 +139,7 @@ namespace ImageProcessor.Web.Processors if (width != null && height != null) { size = new Size( - QueryParamParser.Instance.ParseValue(width), + QueryParamParser.Instance.ParseValue(width), QueryParamParser.Instance.ParseValue(height)); } diff --git a/src/ImageProcessor/Imaging/ResizeLayer.cs b/src/ImageProcessor/Imaging/ResizeLayer.cs index 36176090c..ac6202f83 100644 --- a/src/ImageProcessor/Imaging/ResizeLayer.cs +++ b/src/ImageProcessor/Imaging/ResizeLayer.cs @@ -132,9 +132,15 @@ namespace ImageProcessor.Imaging && this.ResizeMode == resizeLayer.ResizeMode && this.AnchorPosition == resizeLayer.AnchorPosition && this.Upscale == resizeLayer.Upscale - && this.CenterCoordinates.SequenceEqual(resizeLayer.CenterCoordinates) + && ((this.CenterCoordinates != null + && resizeLayer.CenterCoordinates != null + && this.CenterCoordinates.SequenceEqual(resizeLayer.CenterCoordinates)) + || (this.CenterCoordinates == resizeLayer.CenterCoordinates)) && this.MaxSize == resizeLayer.MaxSize - && this.RestrictedSizes.SequenceEqual(resizeLayer.RestrictedSizes); + && ((this.RestrictedSizes != null + && resizeLayer.RestrictedSizes != null + && this.RestrictedSizes.SequenceEqual(resizeLayer.RestrictedSizes)) + || (this.RestrictedSizes == resizeLayer.RestrictedSizes)); } /// diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs index e81eaedd4..a97397200 100644 --- a/src/ImageProcessor/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor/Properties/AssemblyInfo.cs @@ -45,3 +45,4 @@ using System.Runtime.InteropServices; [assembly: AssemblyFileVersion("2.2.0.0")] [assembly: InternalsVisibleTo("ImageProcessor.UnitTests")] +[assembly: InternalsVisibleTo("ImageProcessor.Web")] diff --git a/src/TestWebsites/MVC/Views/Home/Bmp.cshtml b/src/TestWebsites/MVC/Views/Home/Bmp.cshtml index de302f81d..042daa213 100644 --- a/src/TestWebsites/MVC/Views/Home/Bmp.cshtml +++ b/src/TestWebsites/MVC/Views/Home/Bmp.cshtml @@ -12,7 +12,7 @@

Cropped

- +
diff --git a/src/TestWebsites/MVC/Views/Home/Gif.cshtml b/src/TestWebsites/MVC/Views/Home/Gif.cshtml index c46c464bd..fdaaf184e 100644 --- a/src/TestWebsites/MVC/Views/Home/Gif.cshtml +++ b/src/TestWebsites/MVC/Views/Home/Gif.cshtml @@ -11,7 +11,7 @@

Cropped

- +
@@ -68,7 +68,7 @@

Watermark

- +

Format

@@ -80,7 +80,7 @@

Rotate

- +

Quality

diff --git a/src/TestWebsites/MVC/Views/Home/Png.cshtml b/src/TestWebsites/MVC/Views/Home/Png.cshtml index 303c2daaf..2b1c09b19 100644 --- a/src/TestWebsites/MVC/Views/Home/Png.cshtml +++ b/src/TestWebsites/MVC/Views/Home/Png.cshtml @@ -11,7 +11,7 @@

Cropped

- +
@@ -96,9 +96,6 @@

Rounded Corners

-

Old Syntax

- -

New Syntax

diff --git a/src/TestWebsites/MVC/Views/Home/Png8.cshtml b/src/TestWebsites/MVC/Views/Home/Png8.cshtml index 0aaacc6df..5cc537534 100644 --- a/src/TestWebsites/MVC/Views/Home/Png8.cshtml +++ b/src/TestWebsites/MVC/Views/Home/Png8.cshtml @@ -12,7 +12,7 @@

Cropped

- +
diff --git a/src/TestWebsites/MVC/Views/Home/Tiff.cshtml b/src/TestWebsites/MVC/Views/Home/Tiff.cshtml index 5722e5f17..3b13c8a33 100644 --- a/src/TestWebsites/MVC/Views/Home/Tiff.cshtml +++ b/src/TestWebsites/MVC/Views/Home/Tiff.cshtml @@ -11,7 +11,7 @@

Cropped

- +
diff --git a/src/TestWebsites/MVC/Views/Home/WebP.cshtml b/src/TestWebsites/MVC/Views/Home/WebP.cshtml index 27fd95245..8c4e5442a 100644 --- a/src/TestWebsites/MVC/Views/Home/WebP.cshtml +++ b/src/TestWebsites/MVC/Views/Home/WebP.cshtml @@ -12,7 +12,7 @@

Cropped

- +