Ejemplo n.º 1
0
    public void Pattern_CreatesConstraintFromString()
    {
        // Arrange
        var template    = "{a}/{b}/{c}";
        var defaults    = new { };
        var constraints = new { d = "foo", };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.ParameterPolicies.OrderBy(kvp => kvp.Key),
            kvp =>
        {
            Assert.Equal("d", kvp.Key);
            var regex = Assert.IsType <RegexRouteConstraint>(Assert.Single(kvp.Value).ParameterPolicy);
            Assert.Equal("^(foo)$", regex.Constraint.ToString());
        });
    }
Ejemplo n.º 2
0
    public void Pattern_ExtraConstraints_MultipleConstraintsForKey()
    {
        // Arrange
        var template    = "{a}/{b}/{c}";
        var defaults    = new { };
        var constraints = new { d = new object[] { new RegexRouteConstraint("foo"), new RegexRouteConstraint("bar"), "baz" } };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.ParameterPolicies.OrderBy(kvp => kvp.Key),
            kvp =>
        {
            Assert.Equal("d", kvp.Key);
            Assert.Collection(
                kvp.Value,
                c => Assert.Equal("foo", Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy).Constraint.ToString()),
                c => Assert.Equal("bar", Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy).Constraint.ToString()),
                c => Assert.Equal("^(baz)$", Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy).Constraint.ToString()));
        });
    }
Ejemplo n.º 3
0
    public void Pattern_RawTextAndArrayOfSegments_ShouldMakeCopyOfArrayOfSegments()
    {
        // Arrange
        var rawText      = "raw";
        var literalPartA = RoutePatternFactory.LiteralPart("A");
        var paramPartB   = RoutePatternFactory.ParameterPart("B");
        var paramPartC   = RoutePatternFactory.ParameterPart("C");
        var paramPartD   = RoutePatternFactory.ParameterPart("D");
        var segments     = new[]
        {
            RoutePatternFactory.Segment(literalPartA, paramPartB),
            RoutePatternFactory.Segment(paramPartC, literalPartA),
            RoutePatternFactory.Segment(paramPartD),
            RoutePatternFactory.Segment(literalPartA)
        };

        // Act
        var actual = RoutePatternFactory.Pattern(rawText, segments);

        segments[1] = RoutePatternFactory.Segment(RoutePatternFactory.ParameterPart("E"));
        Array.Resize(ref segments, 2);

        // Assert
        Assert.Equal(3, actual.Parameters.Count);
        Assert.Same(paramPartB, actual.Parameters[0]);
        Assert.Same(paramPartC, actual.Parameters[1]);
        Assert.Same(paramPartD, actual.Parameters[2]);
    }
Ejemplo n.º 4
0
    public void Pattern_MergesDefaultValues()
    {
        // Arrange
        var template    = "{a}/{b}/{c=19}";
        var defaults    = new { a = "15", b = 17 };
        var constraints = new { };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Equal("15", actual.GetParameter("a").Default);
        Assert.Equal(17, actual.GetParameter("b").Default);
        Assert.Equal("19", actual.GetParameter("c").Default);

        Assert.Collection(
            actual.Defaults.OrderBy(kvp => kvp.Key),
            kvp => { Assert.Equal("a", kvp.Key); Assert.Equal("15", kvp.Value); },
            kvp => { Assert.Equal("b", kvp.Key); Assert.Equal(17, kvp.Value); },
            kvp => { Assert.Equal("c", kvp.Key); Assert.Equal("19", kvp.Value); });
    }
Ejemplo n.º 5
0
    public void Pattern_ExtraConstraints_RouteConstraint()
    {
        // Arrange
        var template    = "{a}/{b}/{c}";
        var defaults    = new { };
        var constraints = new { d = Mock.Of <IRouteConstraint>(), e = Mock.Of <IRouteConstraint>(), };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.ParameterPolicies.OrderBy(kvp => kvp.Key),
            kvp =>
        {
            Assert.Equal("d", kvp.Key);
            Assert.Collection(
                kvp.Value,
                c => Assert.NotNull(c.ParameterPolicy));
        },
            kvp =>
        {
            Assert.Equal("e", kvp.Key);
            Assert.Collection(
                kvp.Value,
                c => Assert.NotNull(c.ParameterPolicy));
        });
    }
Ejemplo n.º 6
0
        public async Task AddRoutePatternToClaims()
        {
            var context = new DefaultHttpContext();

            context.Request.Method = "POST";
            IEndpointFeature endpointFeature = Substitute.For <IEndpointFeature>();
            RoutePattern     routePattern    = RoutePatternFactory.Pattern("weather/{town}");
            var routeEndpoint = new RouteEndpoint(_ => null, routePattern, default, default, string.Empty);
Ejemplo n.º 7
0
        private RouteEndpoint CreateEndpoint(
            ActionDescriptor action,
            IDictionary <string, string> actionRouteValues,
            string routeName,
            string patternRawText,
            IEnumerable <RoutePatternPathSegment> segments,
            object nonInlineDefaults,
            int order,
            RouteValueDictionary dataTokens,
            bool suppressLinkGeneration,
            bool suppressPathMatching,
            List <Action <EndpointModel> > conventions)
        {
            RequestDelegate requestDelegate = (context) =>
            {
                var routeData = context.GetRouteData();

                var actionContext = new ActionContext(context, routeData, action);

                var invoker = _invokerFactory.CreateInvoker(actionContext);
                return(invoker.InvokeAsync());
            };

            var defaults = new RouteValueDictionary(nonInlineDefaults);

            EnsureRequiredValuesInDefaults(actionRouteValues, defaults, segments);

            var model = new RouteEndpointModel(requestDelegate, RoutePatternFactory.Pattern(patternRawText, defaults, parameterPolicies: null, segments), order);

            AddEndpointMetadata(
                model.Metadata,
                action,
                routeName,
                new RouteValueDictionary(actionRouteValues),
                dataTokens,
                suppressLinkGeneration,
                suppressPathMatching);

            model.DisplayName = action.DisplayName;

            // REVIEW: When should conventions be run
            // Metadata should have lower precedence that data source metadata
            if (conventions != null)
            {
                foreach (var convention in conventions)
                {
                    convention(model);
                }
            }

            return((RouteEndpoint)model.Build());
        }
Ejemplo n.º 8
0
    public static RoutePattern Parse(string pattern)
    {
        if (pattern == null)
        {
            throw new ArgumentNullException(nameof(pattern));
        }

        var trimmedPattern = TrimPrefix(pattern);

        var context  = new Context(trimmedPattern);
        var segments = new List <RoutePatternPathSegment>();

        while (context.MoveNext())
        {
            var i = context.Index;

            if (context.Current == Separator)
            {
                // If we get here is means that there's a consecutive '/' character.
                // Templates don't start with a '/' and parsing a segment consumes the separator.
                throw new RoutePatternException(pattern, Resources.TemplateRoute_CannotHaveConsecutiveSeparators);
            }

            if (!ParseSegment(context, segments))
            {
                throw new RoutePatternException(pattern, context.Error);
            }

            // A successful parse should always result in us being at the end or at a separator.
            Debug.Assert(context.AtEnd() || context.Current == Separator);

            if (context.Index <= i)
            {
                // This shouldn't happen, but we want to crash if it does.
                var message = "Infinite loop detected in the parser. Please open an issue.";
                throw new InvalidProgramException(message);
            }
        }

        if (IsAllValid(context, segments))
        {
            return(RoutePatternFactory.Pattern(pattern, segments));
        }
        else
        {
            throw new RoutePatternException(pattern, context.Error);
        }
    }
Ejemplo n.º 9
0
        private RouteEndpoint CreateEndpoint(
            ActionDescriptor action,
            string routeName,
            string patternRawText,
            IEnumerable <RoutePatternPathSegment> segments,
            object nonInlineDefaults,
            int order,
            object source,
            bool suppressLinkGeneration)
        {
            RequestDelegate requestDelegate = (context) =>
            {
                var values    = context.Features.Get <IRouteValuesFeature>().RouteValues;
                var routeData = new RouteData();
                foreach (var kvp in values)
                {
                    if (kvp.Value != null)
                    {
                        routeData.Values.Add(kvp.Key, kvp.Value);
                    }
                }

                var actionContext = new ActionContext(context, routeData, action);

                var invoker = _invokerFactory.CreateInvoker(actionContext);
                return(invoker.InvokeAsync());
            };

            var defaults = new RouteValueDictionary(nonInlineDefaults);

            EnsureRequiredValuesInDefaults(action.RouteValues, defaults);

            var metadataCollection = BuildEndpointMetadata(
                action,
                routeName,
                new RouteValueDictionary(action.RouteValues),
                source,
                suppressLinkGeneration);

            var endpoint = new RouteEndpoint(
                requestDelegate,
                RoutePatternFactory.Pattern(patternRawText, defaults, parameterPolicies: null, segments),
                order,
                metadataCollection,
                action.DisplayName);

            return(endpoint);
        }
Ejemplo n.º 10
0
        private RouteEndpoint CreateEndpoint(
            ActionDescriptor action,
            IDictionary <string, string> actionRouteValues,
            string routeName,
            string patternRawText,
            object nonParameterPolicies,
            IEnumerable <RoutePatternPathSegment> segments,
            object nonInlineDefaults,
            int order,
            RouteValueDictionary dataTokens,
            bool suppressLinkGeneration,
            bool suppressPathMatching)
        {
            RequestDelegate requestDelegate = (context) =>
            {
                var routeData = context.GetRouteData();

                var actionContext = new ActionContext(context, routeData, action);

                var invoker = _invokerFactory.CreateInvoker(actionContext);
                return(invoker.InvokeAsync());
            };

            var defaults = new RouteValueDictionary(nonInlineDefaults);

            EnsureRequiredValuesInDefaults(actionRouteValues, defaults, segments);

            var metadataCollection = BuildEndpointMetadata(
                action,
                routeName,
                new RouteValueDictionary(actionRouteValues),
                dataTokens,
                suppressLinkGeneration,
                suppressPathMatching);

            var endpoint = new RouteEndpoint(
                requestDelegate,
                RoutePatternFactory.Pattern(patternRawText, defaults, nonParameterPolicies, segments),
                order,
                metadataCollection,
                action.DisplayName);

            return(endpoint);
        }
Ejemplo n.º 11
0
    public void Pattern_ExtraConstraints_NestedArray_Throws()
    {
        // Arrange
        var template    = "{a}/{b}/{c:int}";
        var defaults    = new { };
        var constraints = new { c = new object[] { new object[0] } };

        var original = RoutePatternFactory.Parse(template);

        // Act & Assert
        Assert.Throws <InvalidOperationException>(() =>
        {
            RoutePatternFactory.Pattern(
                original.RawText,
                defaults,
                constraints,
                original.PathSegments);
        });
    }
Ejemplo n.º 12
0
    public void Pattern_MergesConstraints()
    {
        // Arrange
        var template    = "{a:int}/{b}/{c}";
        var defaults    = new { };
        var constraints = new { a = new RegexRouteConstraint("foo"), b = new RegexRouteConstraint("bar") };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.GetParameter("a").ParameterPolicies,
            c => Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy),
            c => Assert.Equal("int", c.Content));
        Assert.Collection(
            actual.GetParameter("b").ParameterPolicies,
            c => Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy));

        Assert.Collection(
            actual.ParameterPolicies.OrderBy(kvp => kvp.Key),
            kvp =>
        {
            Assert.Equal("a", kvp.Key);
            Assert.Collection(
                kvp.Value,
                c => Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy),
                c => Assert.Equal("int", c.Content));
        },
            kvp =>
        {
            Assert.Equal("b", kvp.Key);
            Assert.Collection(
                kvp.Value,
                c => Assert.IsType <RegexRouteConstraint>(c.ParameterPolicy));
        });
    }
Ejemplo n.º 13
0
    public void Pattern_SameDuplicateDefaultValue()
    {
        // Arrange
        var template    = "{a=13}/{b}/{c}";
        var defaults    = new { a = "13", };
        var constraints = new { };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.Defaults,
            kvp => { Assert.Equal("a", kvp.Key); Assert.Equal("13", kvp.Value); });
    }
Ejemplo n.º 14
0
    public void Pattern_InvalidConstraintTypeThrows()
    {
        // Arrange
        var template    = "{a}/{b}/{c}";
        var defaults    = new { };
        var constraints = new { d = 17, };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var ex = Assert.Throws <InvalidOperationException>(() => RoutePatternFactory.Pattern(
                                                               original.RawText,
                                                               defaults,
                                                               constraints,
                                                               original.PathSegments));

        // Assert
        Assert.Equal(
            $"Invalid constraint '17'. A constraint must be of type 'string' or '{typeof(IRouteConstraint)}'.",
            ex.Message);
    }
Ejemplo n.º 15
0
    public void Pattern_OptionalParameterDefaultValue_Throws()
    {
        // Arrange
        var template    = "{a}/{b}/{c?}";
        var defaults    = new { c = "15", };
        var constraints = new { };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var ex = Assert.Throws <InvalidOperationException>(() => RoutePatternFactory.Pattern(
                                                               original.RawText,
                                                               defaults,
                                                               constraints,
                                                               original.PathSegments));

        // Assert
        Assert.Equal(
            "An optional parameter cannot have default value.",
            ex.Message);
    }
Ejemplo n.º 16
0
    public void Pattern_RawTextAndDefaultsAndParameterPoliciesAndArrayOfSegments_ShouldMakeCopyOfArrayOfSegments()
    {
        // Arrange
        var    rawText           = "raw";
        object defaults          = new { B = 12, C = 4 };
        object parameterPolicies = null;
        var    literalPartA      = RoutePatternFactory.LiteralPart("A");
        var    paramPartB        = RoutePatternFactory.ParameterPart("B");
        var    paramPartC        = RoutePatternFactory.ParameterPart("C");
        var    paramPartD        = RoutePatternFactory.ParameterPart("D");
        var    segments          = new[]
        {
            RoutePatternFactory.Segment(literalPartA, paramPartB),
            RoutePatternFactory.Segment(paramPartC, literalPartA),
            RoutePatternFactory.Segment(paramPartD),
            RoutePatternFactory.Segment(literalPartA)
        };

        // Act
        var actual = RoutePatternFactory.Pattern(rawText, defaults, parameterPolicies, segments);

        segments[1] = RoutePatternFactory.Segment(RoutePatternFactory.ParameterPart("E"));
        Array.Resize(ref segments, 2);

        // Assert
        Assert.Equal(3, actual.Parameters.Count);
        Assert.Equal(paramPartB.Name, actual.Parameters[0].Name);
        Assert.Equal(12, actual.Parameters[0].Default);
        Assert.Null(paramPartB.Default);
        Assert.NotSame(paramPartB, actual.Parameters[0]);
        Assert.Equal(paramPartC.Name, actual.Parameters[1].Name);
        Assert.Equal(4, actual.Parameters[1].Default);
        Assert.NotSame(paramPartC, actual.Parameters[1]);
        Assert.Null(paramPartC.Default);
        Assert.Equal(paramPartD.Name, actual.Parameters[2].Name);
        Assert.Null(actual.Parameters[2].Default);
        Assert.Same(paramPartD, actual.Parameters[2]);
        Assert.Null(paramPartD.Default);
    }
Ejemplo n.º 17
0
    public void Pattern_ExtraDefaultValues()
    {
        // Arrange
        var template    = "{a}/{b}/{c}";
        var defaults    = new { d = "15", e = 17 };
        var constraints = new { };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var actual = RoutePatternFactory.Pattern(
            original.RawText,
            defaults,
            constraints,
            original.PathSegments);

        // Assert
        Assert.Collection(
            actual.Defaults.OrderBy(kvp => kvp.Key),
            kvp => { Assert.Equal("d", kvp.Key); Assert.Equal("15", kvp.Value); },
            kvp => { Assert.Equal("e", kvp.Key); Assert.Equal(17, kvp.Value); });
    }
Ejemplo n.º 18
0
    public void Pattern_DifferentDuplicateDefaultValue_Throws()
    {
        // Arrange
        var template    = "{a=13}/{b}/{c}";
        var defaults    = new { a = "15", };
        var constraints = new { };

        var original = RoutePatternFactory.Parse(template);

        // Act
        var ex = Assert.Throws <InvalidOperationException>(() => RoutePatternFactory.Pattern(
                                                               original.RawText,
                                                               defaults,
                                                               constraints,
                                                               original.PathSegments));

        // Assert
        Assert.Equal(
            "The route parameter 'a' has both an inline default value and an explicit default " +
            "value specified. A route parameter cannot contain an inline default value when a " +
            "default value is specified explicitly. Consider removing one of them.",
            ex.Message);
    }
Ejemplo n.º 19
0
        private IReadOnlyList <Endpoint> Update(StaticFileOptionsProvider staticFileOptionsProvider)
        {
            const string HtmlExtension      = ".html";
            const string CatchAllSlugPrefix = "...";

            var staticFileOptions = staticFileOptionsProvider.StaticFileOptions;
            var requestDelegate   = CreateRequestDelegate(this.endpointRouteBuilder, staticFileOptions);
            var endpoints         = new List <Endpoint>();

            foreach (var filePath in TraverseFiles(staticFileOptions.FileProvider))
            {
                if (!filePath.EndsWith(HtmlExtension))
                {
                    continue;
                }

                var fileWithoutHtml = filePath.Substring(0, filePath.Length - HtmlExtension.Length);
                var patternSegments = new List <RoutePatternPathSegment>();
                var segments        = fileWithoutHtml.Split('/');

                // NOTE: Start at 1 because paths here always have a leading slash
                for (int i = 1; i < segments.Length; i++)
                {
                    var segment = segments[i];
                    if (i == segments.Length - 1 && segment == "index")
                    {
                        // Skip `index` segment, match whatever we got so far.
                        // This is so that e.g. file `/a/b/index.html` is served at path `/a/b`, as desired.

                        // TODO: Should we also serve the same file at `/a/b/index`? Note that `/a/b/index.html` will already work
                        // via the UseStaticFiles middleware added by `NextjsStaticHostingExtensions.UseNextjsStaticHosting`.
                        break;
                    }

                    var match = slugRegex.Match(segment);
                    if (match.Success)
                    {
                        string slugName = match.Groups[1].Value;
                        if (slugName.StartsWith(CatchAllSlugPrefix))
                        {
                            // Catch all route -- see: https://nextjs.org/docs/routing/dynamic-routes#catch-all-routes
                            var parameterName = slugName.Substring(CatchAllSlugPrefix.Length);
                            patternSegments.Add(
                                RoutePatternFactory.Segment(
                                    RoutePatternFactory.ParameterPart(parameterName, null, RoutePatternParameterKind.CatchAll)));
                        }
                        else
                        {
                            // Dynamic route -- see: https://nextjs.org/docs/routing/dynamic-routes
                            patternSegments.Add(
                                RoutePatternFactory.Segment(
                                    RoutePatternFactory.ParameterPart(slugName)));
                        }
                    }
                    else
                    {
                        // Literal match
                        patternSegments.Add(
                            RoutePatternFactory.Segment(
                                RoutePatternFactory.LiteralPart(segment)));
                    }
                }
                var endpointBuilder = new RouteEndpointBuilder(requestDelegate, RoutePatternFactory.Pattern(patternSegments), order: DefaultEndpointOrder);

                endpointBuilder.Metadata.Add(new StaticFileEndpointMetadata(filePath));
                endpointBuilder.DisplayName = $"Next.js {filePath}";
                var endpoint = endpointBuilder.Build();
                endpoints.Add(endpoint);
            }

            return(endpoints);
        }
Ejemplo n.º 20
0
        public void PathContextProviderConstructor1()
        {
            var path = new StringValues("SomePathValue1");

            var endpointMock = new Mock <IEndpointFeature>();

            endpointMock.Setup(em => em.Endpoint).Returns(new RouteEndpoint(rd => Task.CompletedTask, RoutePatternFactory.Pattern(path), 0, null, null)
            {
            });

            var featureMock = new Mock <IFeatureCollection>();

            featureMock.Setup(fm => fm[typeof(IEndpointFeature)]).Returns(endpointMock.Object);

            var contextMock = new Mock <HttpContext>();

            contextMock.Setup(cm => cm.Features).Returns(featureMock.Object);

            var accessorMock = new Mock <IHttpContextAccessor>();

            accessorMock.Setup(am => am.HttpContext).Returns(contextMock.Object);

            var contextProvider = new PathContextProvider(accessorMock.Object);

            contextProvider.Path.Should().Be(path);
        }
Ejemplo n.º 21
0
        private static Mock <IHttpContextAccessor> SetUpFullHttpContextAccessor(StringValues correlationId, StringValues forwardedFor, StringValues path, Uri referrer, string remoteIpAddress, string requestMethod, StringValues userAgent)
        {
            var endpointMock = new Mock <IEndpointFeature>();

            endpointMock.Setup(em => em.Endpoint).Returns(new RouteEndpoint(rd => Task.CompletedTask, RoutePatternFactory.Pattern(path), 0, null, null)
            {
            });

            var featureMock = new Mock <IFeatureCollection>();

            featureMock.Setup(fm => fm[typeof(IEndpointFeature)]).Returns(endpointMock.Object);

            var connectionMock = new Mock <ConnectionInfo>();

            connectionMock.Setup(cm => cm.RemoteIpAddress).Returns(IPAddress.Parse(remoteIpAddress));

            var headers = new RequestHeaders(new HeaderDictionary());

            headers.Set(CorrelationId, correlationId);
            headers.Set(ForwardedFor, forwardedFor);
            headers.Set(UserAgent, userAgent);
            headers.Referer = referrer;

            var requestMock = new Mock <HttpRequest>();

            requestMock.Setup(rm => rm.Headers).Returns(headers.Headers);
            requestMock.Setup(rm => rm.Method).Returns(requestMethod);

            var contextMock = new Mock <HttpContext>();

            contextMock.Setup(cm => cm.Request).Returns(requestMock.Object);
            contextMock.Setup(cm => cm.Items).Returns(new Dictionary <object, object>());
            contextMock.Setup(cm => cm.Features).Returns(featureMock.Object);
            contextMock.Setup(cm => cm.Connection).Returns(connectionMock.Object);

            var accessorMock = new Mock <IHttpContextAccessor>();

            accessorMock.Setup(am => am.HttpContext).Returns(contextMock.Object);
            return(accessorMock);
        }
Ejemplo n.º 22
0
        public RoutePattern ToRoutePattern()
        {
            var segments = Segments.Select(s => s.ToRoutePatternPathSegment());

            return(RoutePatternFactory.Pattern(TemplateText, segments));
        }
        public void SetHttpContextAddsAllIntendedExtendedProperties()
        {
            var correlationId   = "CorrelationId1";
            var forwardedFor    = "SomeForwardedForValue1";
            var path            = "SomePathValue1";
            var referrer        = new Uri("http://SomeReferrerValue1");
            var remoteIpAddress = "10.0.0.1";
            var requestMethod   = "SomeRequestMethodValue1";
            var userAgent       = "SomeUserAgentValue1";

            var endpointMock = new Mock <IEndpointFeature>();

            endpointMock.Setup(em => em.Endpoint).Returns(new RouteEndpoint(rd => Task.CompletedTask, RoutePatternFactory.Pattern(path), 0, null, null)
            {
            });

            var featureMock = new Mock <IFeatureCollection>();

            featureMock.Setup(fm => fm[typeof(IEndpointFeature)]).Returns(endpointMock.Object);

            var connectionMock = new Mock <ConnectionInfo>();

            connectionMock.Setup(cm => cm.RemoteIpAddress).Returns(IPAddress.Parse(remoteIpAddress));

            var headers = new RequestHeaders(new HeaderDictionary());

            headers.Set(CorrelationId, correlationId);
            headers.Set(ForwardedFor, forwardedFor);
            headers.Set(UserAgent, userAgent);
            headers.Referer = referrer;

            var requestMock = new Mock <HttpRequest>();

            requestMock.Setup(rm => rm.Headers).Returns(headers.Headers);
            requestMock.Setup(rm => rm.Method).Returns(requestMethod);

            var contextMock = new Mock <HttpContext>();

            contextMock.Setup(cm => cm.Request).Returns(requestMock.Object);
            contextMock.Setup(cm => cm.Items).Returns(new Dictionary <object, object>());
            contextMock.Setup(cm => cm.Features).Returns(featureMock.Object);
            contextMock.Setup(cm => cm.Connection).Returns(connectionMock.Object);

            var logEntry = new LogEntry();

            logEntry.SetHttpContext(contextMock.Object);

            logEntry.CorrelationId.Should().Be(correlationId);
            logEntry.ExtendedProperties["X-Forwarded-For"].Should().Be(forwardedFor);
            logEntry.ExtendedProperties["Path"].Should().Be(path);
            logEntry.ExtendedProperties["Referrer"].Should().Be(referrer.ToString());
            logEntry.ExtendedProperties["RemoteIpAddress"].Should().Be(remoteIpAddress);
            logEntry.ExtendedProperties["Method"].Should().Be(requestMethod.ToUpperInvariant());
            logEntry.ExtendedProperties["UserAgent"].Should().Be(userAgent);
        }