コード例 #1
0
        public void add_parameter_should_add_descriptor_for_query_parameter()
        {
            // arrange
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string))).Object;
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = new QueryStringApiVersionReader()
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata, options);

            // act
            context.AddParameter("api-version", Query);

            // assert
            description.ParameterDescriptions.Single().Should().BeEquivalentTo(
                new
            {
                Name          = "api-version",
                ModelMetadata = modelMetadata,
                Source        = BindingSource.Query,
                DefaultValue  = (object)"1.0",
                IsRequired    = true,
                Type          = typeof(string),
            },
                o => o.ExcludingMissingMembers());
        }
コード例 #2
0
        public void add_parameter_should_add_descriptor_for_header()
        {
            // arrange
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = new HeaderApiVersionReader()
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            // act
            context.AddParameter("api-version", Header);

            // assert
            description.ParameterDescriptions.Single().Should().BeEquivalentTo(
                new
            {
                Name          = "api-version",
                ModelMetadata = modelMetadata,
                Source        = BindingSource.Header,
                RouteInfo     = new ApiParameterRouteInfo()
                {
                    DefaultValue = "1.0",
                    IsOptional   = false
                },
                Type = typeof(string)
            },
                o => o.ExcludingMissingMembers());
        }
コード例 #3
0
        public void add_parameter_should_add_optional_parameter_when_allowed()
        {
            // arrange
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion                   = version,
                ApiVersionParameterSource           = new QueryStringApiVersionReader(),
                AssumeDefaultVersionWhenUnspecified = true
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            // act
            context.AddParameter("api-version", Query);

            // assert
            description.ParameterDescriptions.Single().Should().BeEquivalentTo(
                new
            {
                Name          = "api-version",
                ModelMetadata = modelMetadata,
                Source        = BindingSource.Query,
                RouteInfo     = new ApiParameterRouteInfo()
                {
                    DefaultValue = "1.0",
                    IsOptional   = true
                },
                Type = typeof(string)
            },
                o => o.ExcludingMissingMembers());
        }
コード例 #4
0
        public void add_parameter_should_not_add_query_parameter_after_path_parameter_has_been_added()
        {
            // arrange
            var parameter = new ApiParameterDescription()
            {
                Name      = "api-version",
                RouteInfo = new ApiParameterRouteInfo()
                {
                    Constraints = new IRouteConstraint[] { new ApiVersionRouteConstraint() }
                },
                Source = BindingSource.Path
            };
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version, parameter);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = Combine(new QueryStringApiVersionReader(), new UrlSegmentApiVersionReader())
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            modelMetadata.SetupGet(m => m.DataTypeName).Returns(nameof(ApiVersion));

            // act
            context.AddParameter("api-version", Path);
            context.AddParameter("api-version", Query);

            // assert
            description.ParameterDescriptions.Should().HaveCount(1);
        }
        public void add_parameter_should_remove_other_descriptors_after_path_parameter_is_added()
        {
            // arrange
            var parameter = new ApiParameterDescription()
            {
                Name      = "api-version",
                RouteInfo = new ApiParameterRouteInfo()
                {
                    Constraints = new IRouteConstraint[] { new ApiVersionRouteConstraint() }
                },
                Source = BindingSource.Path
            };
            var description = new ApiDescription()
            {
                ParameterDescriptions = { parameter }
            };
            var version       = new ApiVersion(1, 0);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = Combine(new QueryStringApiVersionReader(), new UrlSegmentApiVersionReader())
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            modelMetadata.SetupGet(m => m.DataTypeName).Returns(nameof(ApiVersion));

            // act
            context.AddParameter("api-version", Query);
            context.AddParameter("api-version", Path);

            // assert
            description.ParameterDescriptions.Single().ShouldBeEquivalentTo(
                new
            {
                Name          = "api-version",
                ModelMetadata = modelMetadata,
                Source        = BindingSource.Path,
                RouteInfo     = new ApiParameterRouteInfo()
                {
                    DefaultValue = "1.0",
                    IsOptional   = false,
                    Constraints  = parameter.RouteInfo.Constraints
                },
                Type = typeof(string)
            },
                o => o.ExcludingMissingMembers());
        }
コード例 #6
0
        public void add_parameter_should_add_descriptor_for_media_type_parameter()
        {
            // arrange
            const string Json        = "application/json";
            var          version     = new ApiVersion(1, 0);
            var          description = new ApiDescription()
            {
                ActionDescriptor = new ActionDescriptor()
                {
                    Properties = { [typeof(ApiVersionModel)] = new ApiVersionModel(version) }
                },
                SupportedRequestFormats =
                {
                    new ApiRequestFormat()
                    {
                        MediaType = Json
                    }
                },
                SupportedResponseTypes =
                {
                    new ApiResponseType()
                    {
                        ApiResponseFormats =
                        {
                            new ApiResponseFormat()
                            {
                                MediaType = Json
                            }
                        }
                    }
                }
            };
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = new MediaTypeApiVersionReader()
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            // act
            context.AddParameter("v", MediaTypeParameter);

            // assert
            description.SupportedRequestFormats.Single().MediaType.Should().Be("application/json; v=1.0");
            description.SupportedResponseTypes.Single().ApiResponseFormats.Single().MediaType.Should().Be("application/json; v=1.0");
        }
        public ApiVersionParameterDescriptionContext(
            ApiDescription apiDescription,
            ApiVersion apiVersion,
            ModelMetadata modelMetadata,
            ApiExplorerOptions options)
        {
            Arg.NotNull(apiDescription, nameof(apiDescription));
            Arg.NotNull(apiVersion, nameof(apiVersion));
            Arg.NotNull(modelMetadata, nameof(modelMetadata));
            Arg.NotNull(options, nameof(options));

            ApiDescription = apiDescription;
            ApiVersion     = apiVersion;
            ModelMetadata  = modelMetadata;
            Options        = options;
            optional       = options.AssumeDefaultVersionWhenUnspecified && apiVersion == options.DefaultApiVersion;
        }
コード例 #8
0
        public ApiVersionParameterDescriptionContext(
            ApiDescription apiDescription,
            ApiVersion apiVersion,
            ModelMetadata modelMetadata,
            ApiExplorerOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            ApiDescription = apiDescription;
            ApiVersion     = apiVersion;
            ModelMetadata  = modelMetadata;
            Options        = options;
            optional       = options.AssumeDefaultVersionWhenUnspecified && apiVersion == options.DefaultApiVersion;
            versionNeutral = new Lazy <bool>(() => ApiDescription.ActionDescriptor.GetApiVersionModel().IsApiVersionNeutral);
        }
コード例 #9
0
        public ApiVersionParameterDescriptionContext(
            ApiDescription apiDescription,
            ApiVersion apiVersion,
            ModelMetadata modelMetadata,
            ApiExplorerOptions options)
        {
            Arg.NotNull(apiDescription, nameof(apiDescription));
            Arg.NotNull(apiVersion, nameof(apiVersion));
            Arg.NotNull(modelMetadata, nameof(modelMetadata));
            Arg.NotNull(options, nameof(options));

            ApiDescription = apiDescription;
            ApiVersion     = apiVersion;
            ModelMetadata  = modelMetadata;
            Options        = options;
            optional       = options.AssumeDefaultVersionWhenUnspecified && apiVersion == options.DefaultApiVersion;
            versionNeutral = new Lazy <bool>(() => ApiDescription.ActionDescriptor.GetApiVersionModel().IsApiVersionNeutral);
        }
コード例 #10
0
        public void add_parameter_should_add_descriptor_for_path()
        {
            // arrange
            var parameter = new ApiParameterDescription()
            {
                Name      = "api-version",
                RouteInfo = new ApiParameterRouteInfo()
                {
                    Constraints = new IRouteConstraint[] { new ApiVersionRouteConstraint() }
                },
                Source = BindingSource.Path
            };
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version, parameter);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string))).Object;
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = new UrlSegmentApiVersionReader()
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata, options);

            // act
            context.AddParameter("api-version", Path);

            // assert
            description.ParameterDescriptions.Single().Should().BeEquivalentTo(
                new
            {
                Name          = "api-version",
                ModelMetadata = modelMetadata,
                Source        = BindingSource.Path,
                DefaultValue  = (object)"1.0",
                IsRequired    = true,
                RouteInfo     = new ApiParameterRouteInfo()
                {
                    DefaultValue = "1.0",
                    IsOptional   = false,
                    Constraints  = parameter.RouteInfo.Constraints,
                },
                Type = typeof(string),
            },
                o => o.ExcludingMissingMembers());
        }
コード例 #11
0
        public void add_parameter_should_make_parameters_optional_after_first_parameter()
        {
            // arrange
            var version       = new ApiVersion(1, 0);
            var description   = NewApiDescription(version);
            var modelMetadata = new Mock <ModelMetadata>(ModelMetadataIdentity.ForType(typeof(string)));
            var options       = new ApiExplorerOptions()
            {
                DefaultApiVersion         = version,
                ApiVersionParameterSource = Combine(new QueryStringApiVersionReader(), new HeaderApiVersionReader())
            };
            var context = new ApiVersionParameterDescriptionContext(description, version, modelMetadata.Object, options);

            // act
            context.AddParameter("api-version", Query);
            context.AddParameter("api-version", Header);

            // assert
            description.ParameterDescriptions[0].RouteInfo.IsOptional.Should().BeFalse();
            description.ParameterDescriptions[1].RouteInfo.IsOptional.Should().BeTrue();
        }
コード例 #12
0
        /// <summary>
        /// Attempts to update the relate path of the specified API description and remove the corresponding parameter according to the specified options.
        /// </summary>
        /// <param name="apiDescription">The <see cref="ApiDescription">API description</see> to attempt to update.</param>
        /// <param name="options">The current <see cref="ApiExplorerOptions">API Explorer options</see>.</param>
        /// <returns>True if the <paramref name="apiDescription">API description</paramref> was updated; otherwise, false.</returns>
        public static bool TryUpdateRelativePathAndRemoveApiVersionParameter(this ApiDescription apiDescription, ApiExplorerOptions options)
        {
            Arg.NotNull(apiDescription, nameof(apiDescription));
            Arg.NotNull(options, nameof(options));

            if (!options.SubstituteApiVersionInUrl)
            {
                return(false);
            }

            var parameter = apiDescription.ParameterDescriptions.FirstOrDefault(pd => pd.Source == Path && pd.ModelMetadata?.DataTypeName == nameof(ApiVersion));

            if (parameter == null)
            {
                return(false);
            }

            var relativePath    = apiDescription.RelativePath;
            var token           = '{' + parameter.Name + '}';
            var value           = apiDescription.GetApiVersion().ToString(options.SubstitutionFormat, InvariantCulture);
            var newRelativePath = relativePath.Replace(token, value);

            if (relativePath == newRelativePath)
            {
                return(false);
            }

            apiDescription.RelativePath = newRelativePath;
            apiDescription.ParameterDescriptions.Remove(parameter);
            return(true);
        }
コード例 #13
0
        /// <summary>
        /// Attempts to update the relate path of the specified API description and remove the corresponding parameter according to the specified options.
        /// </summary>
        /// <param name="apiDescription">The <see cref="ApiDescription">API description</see> to attempt to update.</param>
        /// <param name="options">The current <see cref="ApiExplorerOptions">API Explorer options</see>.</param>
        /// <returns>True if the <paramref name="apiDescription">API description</paramref> was updated; otherwise, false.</returns>
        public static bool TryUpdateRelativePathAndRemoveApiVersionParameter(this ApiDescription apiDescription, ApiExplorerOptions options)
        {
            if (apiDescription == null)
            {
                throw new ArgumentNullException(nameof(apiDescription));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (!options.SubstituteApiVersionInUrl)
            {
                return(false);
            }

            var parameter = apiDescription.ParameterDescriptions.FirstOrDefault(pd => pd.Source == Path && pd.ModelMetadata?.DataTypeName == nameof(ApiVersion));

            if (parameter == null)
            {
                return(false);
            }

            var relativePath = apiDescription.RelativePath;
            var token        = '{' + parameter.Name + '}';
            var value        = apiDescription.GetApiVersion().ToString(options.SubstitutionFormat, InvariantCulture);

#if NETSTANDARD2_0
            var newRelativePath = relativePath.Replace(token, value);
#else
            var newRelativePath = relativePath.Replace(token, value, StringComparison.Ordinal);
#endif

            if (relativePath == newRelativePath)
            {
                return(false);
            }

            apiDescription.RelativePath = newRelativePath;
            apiDescription.ParameterDescriptions.Remove(parameter);
            return(true);
        }
        public void versioned_api_explorer_should_group_and_order_descriptions_on_providers_executed()
        {
            // arrange
            var actionProvider        = new TestActionDescriptorCollectionProvider();
            var context               = new ApiDescriptionProviderContext(actionProvider.ActionDescriptors.Items);
            var modelMetadataProvider = NewModelMetadataProvider();
            var apiExplorerOptions    = new ApiExplorerOptions()
            {
                GroupNameFormat = "'v'VVV"
            };
            var apiExplorer = new VersionedApiDescriptionProvider(modelMetadataProvider, Options.Create(apiExplorerOptions));

            foreach (var action in context.Actions)
            {
                context.Results.Add(new ApiDescription()
                {
                    ActionDescriptor = action
                });
            }

            // act
            apiExplorer.OnProvidersExecuted(context);

            // assert
            context.Results.Should().BeEquivalentTo(
                new[]
            {
                // orders
                new { GroupName = "v0.9", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(0, 9)
                      } },
                new { GroupName = "v1", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(1, 0)
                      } },
                new { GroupName = "v1", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(1, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },

                // people
                new { GroupName = "v0.9", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(0, 9)
                      } },
                new { GroupName = "v1", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(1, 0)
                      } },
                new { GroupName = "v1", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(1, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v2", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(2, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
                new { GroupName = "v3", Properties = new Dictionary <object, object>()
                      {
                          [typeof(ApiVersion)] = new ApiVersion(3, 0)
                      } },
            },
                options => options.ExcludingMissingMembers());
        }