Пример #1
0
        public async Task AssetMiddleware_NoAssetMatch()
        {
            IAsset asset;
            var    pipeline = new Mock <IAssetPipeline>();

            pipeline.Setup(p => p.TryGetAssetFromRoute(It.IsAny <string>(), out asset))
            .Returns(false);

            var context = new Mock <HttpContext>();

            context.Setup(c => c.Request.Path).Returns("/file.css");

            var next  = new Mock <RequestDelegate>();
            var env   = new HostingEnvironment();
            var cache = new Mock <IMemoryCache>();

            var options = new WebOptimizerOptions()
            {
                EnableCaching = false
            };
            var amo = new Mock <IOptionsSnapshot <WebOptimizerOptions> >();

            amo.SetupGet(a => a.Value).Returns(options);

            var logger     = new Mock <ILogger <AssetMiddleware> >();
            var builder    = new Mock <IAssetBuilder>();
            var middleware = new AssetMiddleware(next.Object, pipeline.Object, logger.Object, builder.Object);

            await middleware.InvokeAsync(context.Object, amo.Object);

            next.Verify(n => n(context.Object), Times.Once);
        }
Пример #2
0
        public async Task AssetBiulder_NonExistentFileRequested()
        {
            var options = new WebOptimizerOptions();
            var asset   = new Mock <IAsset>().SetupAllProperties();

            asset.Setup(a => a.GenerateCacheKey(It.IsAny <HttpContext>())).Throws <FileNotFoundException>();


            StringValues values;
            var          response = new Mock <HttpResponse>().SetupAllProperties();

            response.Setup(r => r.Headers.Keys).Returns(new string[] { });
            var context = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values)).Returns(false);
            context.Setup(c => c.Response).Returns(response.Object);
            context.Setup(c => c.Request.Path).Returns("/nonexist_file.css");

            var cache = new Mock <IMemoryCache>();

            var store   = new Mock <IAssetResponseStore>();
            var logger  = new Mock <ILogger <AssetBuilder> >();
            var env     = new Mock <IWebHostEnvironment>().SetupAllProperties();
            var builder = new AssetBuilder(cache.Object, store.Object, logger.Object, env.Object);
            var result  = await builder.BuildAsync(asset.Object, context.Object, options).ConfigureAwait(false);

            Assert.Null(result);
        }
Пример #3
0
        public async Task AssetMiddleware_Cache()
        {
            var cssContent = "*{color:red}".AsByteArray();

            var pipeline = new AssetPipeline();
            var options  = new WebOptimizerOptions()
            {
                EnableCaching = false
            };
            var asset = new Mock <IAsset>().SetupAllProperties();

            asset.SetupGet(a => a.ContentType).Returns("text/css");
            asset.SetupGet(a => a.Route).Returns("/file.css");
            asset.Setup(a => a.ExecuteAsync(It.IsAny <HttpContext>(), options))
            .Returns(Task.FromResult(cssContent));

            StringValues values;
            var          response = new Mock <HttpResponse>().SetupAllProperties();
            var          context  = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values))
            .Returns(false);
            context.Setup(c => c.Response)
            .Returns(response.Object);

            context.Setup(c => c.Request.Path).Returns("/file.css");
            context.Setup(c => c.Features.Get <IHttpsCompressionFeature>()).Returns((IHttpsCompressionFeature)null);

            var next  = new Mock <RequestDelegate>();
            var env   = new HostingEnvironment();
            var cache = new Mock <IMemoryCache>();
            var mcr   = new AssetResponse(cssContent, null);

            object bytes = mcr;

            cache.Setup(c => c.TryGetValue(It.IsAny <string>(), out bytes))
            .Returns(true);

            pipeline._assets = new ConcurrentDictionary <string, IAsset>();
            pipeline._assets.TryAdd(asset.Object.Route, asset.Object);

            var amo = new Mock <IOptionsSnapshot <WebOptimizerOptions> >();

            amo.SetupGet(a => a.Value).Returns(options);

            var logger  = new Mock <ILogger <AssetMiddleware> >();
            var builder = new Mock <IAssetBuilder>();

            builder.Setup(b => b.BuildAsync(It.IsAny <IAsset>(), context.Object, options)).Returns(Task.FromResult <IAssetResponse>(mcr));
            var middleware = new AssetMiddleware(next.Object, pipeline, logger.Object, builder.Object);
            var stream     = new MemoryStream();

            response.Setup(r => r.Body).Returns(stream);
            await middleware.InvokeAsync(context.Object, amo.Object);

            Assert.Equal("text/css", context.Object.Response.ContentType);
            Assert.Equal(cssContent, await stream.AsBytesAsync());
            Assert.Equal(0, response.Object.StatusCode);
        }
Пример #4
0
        public async Task AssetMiddleware_NoCache()
        {
            string cssContent = "*{color:red}";

            var pipeline = new AssetPipeline();
            var options  = new WebOptimizerOptions()
            {
                EnableCaching = false
            };
            var asset = new Mock <IAsset>().SetupAllProperties();

            asset.SetupGet(a => a.ContentType).Returns("text/css");
            asset.SetupGet(a => a.Route).Returns("/file.css");
            asset.Setup(a => a.ExecuteAsync(It.IsAny <HttpContext>(), options))
            .Returns(Task.FromResult(cssContent.AsByteArray()));

            StringValues values;
            var          response = new Mock <HttpResponse>().SetupAllProperties();
            var          context  = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values))
            .Returns(false);
            context.Setup(c => c.Response)
            .Returns(response.Object);

            context.Setup(c => c.Request.Path).Returns("/file.css");

            response.SetupGet(c => c.Headers)
            .Returns(new HeaderDictionary());

            var next  = new Mock <RequestDelegate>();
            var env   = new HostingEnvironment();
            var cache = new Mock <IMemoryCache>();

            var member = pipeline.GetType().GetField("_assets", BindingFlags.NonPublic | BindingFlags.Instance);

            member.SetValue(pipeline, new List <IAsset> {
                asset.Object
            });

            var amo = new Mock <IOptionsSnapshot <WebOptimizerOptions> >();

            amo.SetupGet(a => a.Value).Returns(options);

            var mcr     = new AssetResponse(cssContent.AsByteArray(), null);
            var logger  = new Mock <ILogger <AssetMiddleware> >();
            var builder = new Mock <IAssetBuilder>();

            builder.Setup(b => b.BuildAsync(It.IsAny <IAsset>(), context.Object, options)).Returns(Task.FromResult <IAssetResponse>(mcr));
            var middleware = new AssetMiddleware(next.Object, pipeline, logger.Object, builder.Object);
            var stream     = new MemoryStream();

            response.Setup(r => r.Body).Returns(stream);
            await middleware.InvokeAsync(context.Object, amo.Object);

            Assert.Equal("text/css", context.Object.Response.ContentType);
            Assert.Equal(cssContent.AsByteArray(), await stream.AsBytesAsync());
            Assert.Equal(0, response.Object.StatusCode);
        }
Пример #5
0
        public async Task AssetBuilder_NoMemoryCache()
        {
            byte[] cssContent = "*{color:red}".AsByteArray();

            var pipeline = new AssetPipeline();
            var options  = new WebOptimizerOptions()
            {
                EnableMemoryCache = false
            };
            var asset = new Mock <IAsset>().SetupAllProperties();

            asset.SetupGet(a => a.ContentType).Returns("text/css");
            asset.SetupGet(a => a.Route).Returns("/file.css");
            asset.Setup(a => a.GenerateCacheKey(It.IsAny <HttpContext>())).Returns("cachekey");
            asset.Setup(a => a.ExecuteAsync(It.IsAny <HttpContext>(), options))
            .Returns(Task.FromResult(cssContent));

            StringValues values;
            var          response = new Mock <HttpResponse>().SetupAllProperties();

            response.Setup(r => r.Headers.Keys).Returns(new string[] { });
            var context = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values)).Returns(false);
            context.Setup(c => c.Response).Returns(response.Object);
            context.Setup(c => c.Request.Path).Returns("/file.css");

            var next = new Mock <RequestDelegate>();
            var env  = new Mock <IHostingEnvironment>().SetupAllProperties();

            env.Setup(e => e.ContentRootPath).Returns(@"D:\Project\");

            object bytes;
            var    cache = new Mock <IMemoryCache>();

            cache.Setup(c => c.TryGetValue(It.IsAny <string>(), out bytes)).Throws <InvalidOperationException>();

            var store = new Mock <IAssetResponseStore>();

            var member = pipeline.GetType().GetField("_assets", BindingFlags.NonPublic | BindingFlags.Instance);

            member.SetValue(pipeline, new List <IAsset> {
                asset.Object
            });

            var amo = new Mock <IOptionsSnapshot <WebOptimizerOptions> >();

            amo.SetupGet(a => a.Value).Returns(options);

            var logger  = new Mock <ILogger <AssetBuilder> >();
            var builder = new AssetBuilder(cache.Object, store.Object, logger.Object, env.Object);

            var result = await builder.BuildAsync(asset.Object, context.Object, options).ConfigureAwait(false);

            Assert.Equal(cssContent, result.Body);
        }
Пример #6
0
        public async Task AssetBuilder_NoDiskCache()
        {
            byte[] cssContent = "*{color:red}".AsByteArray();

            var pipeline = new AssetPipeline();
            var options  = new WebOptimizerOptions()
            {
                EnableDiskCache = false
            };
            var asset = new Mock <IAsset>().SetupAllProperties();

            asset.SetupGet(a => a.ContentType).Returns("text/css");
            asset.SetupGet(a => a.Route).Returns("/file.css");
            asset.Setup(a => a.GenerateCacheKey(It.IsAny <HttpContext>())).Returns("cachekey");
            asset.Setup(a => a.ExecuteAsync(It.IsAny <HttpContext>(), options))
            .Returns(Task.FromResult(cssContent));

            StringValues values;
            var          response = new Mock <HttpResponse>().SetupAllProperties();

            response.Setup(r => r.Headers.Keys).Returns(new string[] { });
            var context = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values)).Returns(false);
            context.Setup(c => c.Response).Returns(response.Object);
            context.Setup(c => c.Request.Path).Returns("/file.css");

            var next = new Mock <RequestDelegate>();
            var env  = new Mock <IWebHostEnvironment>().SetupAllProperties();

            env.Setup(e => e.ContentRootPath).Returns(@"D:\Project\");

            var mco = new Mock <IOptions <MemoryCacheOptions> >();

            mco.SetupGet(o => o.Value).Returns(new MemoryCacheOptions());
            var cache = new MemoryCache(mco.Object);

            AssetResponse ar;
            var           store = new Mock <IAssetResponseStore>();

            store.Setup(s => s.TryGet(It.IsAny <string>(), It.IsAny <string>(), out ar)).Throws <InvalidOperationException>();

            pipeline._assets = new ConcurrentDictionary <string, IAsset>();
            pipeline._assets.TryAdd(asset.Object.Route, asset.Object);

            var logger  = new Mock <ILogger <AssetBuilder> >();
            var builder = new AssetBuilder(cache, store.Object, logger.Object, env.Object);

            var result = await builder.BuildAsync(asset.Object, context.Object, options).ConfigureAwait(false);

            Assert.Equal(cssContent, result.Body);
        }
Пример #7
0
        internal static WebOptimizerOptions GetWebOptimizerOptions(this IServiceProvider serviceProvider,
                                                                   IWebHostEnvironment env)
        {
            if (_webOptimizerOptions == null)
            {
                var options = ((IOptionsSnapshot <WebOptimizerOptions>)
                               serviceProvider.GetService(typeof(IOptionsSnapshot <WebOptimizerOptions>)))
                              .Value;

                _webOptimizerOptions = options;
            }

            return(_webOptimizerOptions);
        }
Пример #8
0
        public async Task AssetMiddleware_NoCache_EmptyResponse()
        {
            var pipeline = new AssetPipeline();
            var options  = new WebOptimizerOptions()
            {
                EnableCaching = false
            };
            var asset = new Mock <IAsset>().SetupAllProperties();

            asset.SetupGet(a => a.ContentType).Returns("text/css");
            asset.SetupGet(a => a.Route).Returns("/file.css");
            asset.Setup(a => a.ExecuteAsync(It.IsAny <HttpContext>(), options))
            .Returns(Task.FromResult(new byte[0]));

            StringValues values;
            var          context = new Mock <HttpContext>().SetupAllProperties();

            context.Setup(s => s.Request.Headers.TryGetValue("Accept-Encoding", out values))
            .Returns(false);

            context.Setup(c => c.Request.Path).Returns("/file.css");

            context.SetupGet(c => c.Response.Headers)
            .Returns(new HeaderDictionary());

            var next  = new Mock <RequestDelegate>();
            var env   = new HostingEnvironment();
            var cache = new Mock <IMemoryCache>();

            var member = pipeline.GetType().GetField("_assets", BindingFlags.NonPublic | BindingFlags.Instance);

            member.SetValue(pipeline, new List <IAsset> {
                asset.Object
            });

            var amo = new Mock <IOptionsSnapshot <WebOptimizerOptions> >();

            amo.SetupGet(a => a.Value).Returns(options);

            var logger     = new Mock <ILogger <AssetMiddleware> >();
            var builder    = new Mock <IAssetBuilder>();
            var middleware = new AssetMiddleware(next.Object, pipeline, logger.Object, builder.Object);

            var stream = new MemoryStream();

            await middleware.InvokeAsync(context.Object, amo.Object);

            next.Verify(n => n(context.Object), Times.Once);
        }
Пример #9
0
        internal static WebOptimizerOptions GetWebOptimizerOptions(this IServiceProvider serviceProvider,
                                                                   IHostingEnvironment env)
        {
            if (_webOptimizerOptions == null)
            {
                var options = ((IOptionsSnapshot <WebOptimizerOptions>)
                               serviceProvider.GetService(typeof(IOptionsSnapshot <WebOptimizerOptions>)))
                              .Value;

                //Ensures that defaults are set
                options.EnableCaching           = options.EnableCaching ?? !env.IsDevelopment();
                options.EnableTagHelperBundling = options.EnableTagHelperBundling ?? true;
                _webOptimizerOptions            = options;
            }

            return(_webOptimizerOptions);
        }
Пример #10
0
        internal static bool HandleBundle(Func <IAssetPipeline, string, IAsset> createAsset,
                                          IServiceProvider serviceProvider,
                                          IWebHostEnvironment env,
                                          TagHelperOutput output,
                                          HttpContext httpContext,
                                          string attrName,
                                          string attrValue,
                                          string bundleKey,
                                          string destBundleKey
                                          )
        {
            if (string.IsNullOrEmpty(bundleKey) == false)
            {
                WebOptimizerOptions options = serviceProvider.GetWebOptimizerOptions(env);

                if (options.EnableTagHelperBundling == true)
                {
                    if (string.IsNullOrEmpty(attrValue))
                    {
                        return(true);
                    }

                    output.SuppressOutput();

                    IAssetPipeline pipeline  = serviceProvider.GetAssetPipeline();
                    var            assetKey  = GetKey(serviceProvider, bundleKey);
                    var            assetItem = GetOrCreateAssetByKey(pipeline, assetKey, createAsset);
                    if (assetItem.Initialized)
                    {
                        return(true);
                    }
                    string cleanRoute = attrValue.TrimStart('~');

                    lock (assetItem.Asset.SourceFiles)
                    {
                        ((HashSet <string>)assetItem.Asset.SourceFiles).Add(cleanRoute);
                    }

                    return(true);
                }
            }

            if (string.IsNullOrEmpty(destBundleKey) == false)
            {
                WebOptimizerOptions options = serviceProvider.GetWebOptimizerOptions(env);

                if (options.EnableTagHelperBundling == true)
                {
                    IAssetPipeline pipeline  = serviceProvider.GetAssetPipeline();
                    var            assetKey  = GetKey(serviceProvider, destBundleKey);
                    var            assetItem = GetOrCreateAssetByKey(pipeline, assetKey, createAsset);
                    assetItem.Initialized = true;
                    attrValue             = GenerateHash(assetItem.Asset, httpContext);

                    output.Attributes.SetAttribute(attrName, attrValue);
                    return(true);
                }

                output.SuppressOutput();
                return(true);
            }

            return(false);
        }