public async Task ExecutePublishDocumentServer_With_SchemaFile_Handler()
        {
            // arrange
            string sessionId = await SessionCreator.CreateSessionAsync();

            var handler = new PublishNewSchemaDocumentHandler(
                Storage, SchemaRepository, PublishSchemaEventSender);

            using var service = new PublishDocumentService(
                      PublishDocumentMessageReceiver, new
                      IPublishDocumentHandler[] { handler });

            var schema = new Schema("abc", "def");
            await SchemaRepository.AddSchemaAsync(schema);

            var environment = new Environment("abc", "def");
            await EnvironmentRepository.AddEnvironmentAsync(environment);

            var message = new PublishDocumentMessage(
                sessionId,
                environment.Id,
                schema.Id,
                "externalId",
                Array.Empty <DocumentInfo>(),
                Array.Empty <Tag>());

            IFileContainer fileContainer = await Storage.CreateContainerAsync(sessionId);

            byte[] buffer = Encoding.UTF8.GetBytes(@"
                    type Query {
                        foo: String
                    }
                ");
            await fileContainer.CreateFileAsync("schema.graphql", buffer, 0, buffer.Length);

            await PublishDocumentMessageSender.SendAsync(message);

            // act
            await service.StartAsync(default);
        public void GenerateSchema_SetsValidationProperties_IfDataAnnotatedType()
        {
            var schemaRepository = new SchemaRepository();

            var referenceSchema = Subject().GenerateSchema(typeof(DataAnnotatedType), schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.Equal(1, schema.Properties["IntWithRange"].Minimum);
            Assert.Equal(12, schema.Properties["IntWithRange"].Maximum);
            Assert.Equal("^[3-6]?\\d{12,15}$", schema.Properties["StringWithRegularExpression"].Pattern);
            Assert.Equal(5, schema.Properties["StringWithStringLength"].MinLength);
            Assert.Equal(10, schema.Properties["StringWithStringLength"].MaxLength);
            Assert.Equal(1, schema.Properties["StringWithMinMaxLength"].MinLength);
            Assert.Equal(3, schema.Properties["StringWithMinMaxLength"].MaxLength);
            Assert.Equal(new[] { "IntWithRequired", "StringWithRequired" }, schema.Required.ToArray());
            Assert.Equal("date", schema.Properties["StringWithDataTypeDate"].Format);
            Assert.Equal("date-time", schema.Properties["StringWithDataTypeDateTime"].Format);
            Assert.Equal("password", schema.Properties["StringWithDataTypePassword"].Format);
            Assert.IsType <OpenApiString>(schema.Properties["StringWithDefaultValue"].Default);
            Assert.Equal("foobar", ((OpenApiString)schema.Properties["StringWithDefaultValue"].Default).Value);
        }
示例#3
0
        public async void TestDeleteAsync()
        {
            var options = new DbContextOptionsBuilder <ApplicationDbContext>()
                          .UseInMemoryDatabase(databaseName: "SchemaDatabase")
                          .Options;

            var dbContext = new ApplicationDbContext(options);
            var repo      = new SchemaRepository(dbContext);
            // Act
            var newSchema = await repo.CreateAsync(new Schema { SavedDate = DateTime.Now, SchemaJson = "{id: 123}" });

            var createdId = newSchema.Id;
            await repo.DeleteAsync(createdId);

            var searchResult = await repo.FindByAsync(x => x.Id == createdId);

            if (searchResult.Count() == 0)
            {
            }
            // Assert
            Assert.True(createdId > 0 && searchResult.Count() == 0);
        }
        public void GenerateSchema_SupportsOptionToGeneratePolymorphicSchemas()
        {
            var subject = Subject(c =>
            {
                c.GeneratePolymorphicSchemas = true;
            });
            var modelMetadata    = _modelMetadataProvider.GetMetadataForType(typeof(PolymorphicType));
            var schemaRepository = new SchemaRepository();

            var referenceSchema = subject.GenerateSchema(modelMetadata, schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.NotNull(schema.OneOf);
            Assert.Equal(2, schema.OneOf.Count);
            Assert.NotNull(schema.OneOf[0].Reference);
            Assert.Equal("SubType1", schema.OneOf[0].Reference.Id);
            Assert.Equal(new[] { "Property1", "BaseProperty" }, schemaRepository.Schemas["SubType1"].Properties.Keys);
            Assert.NotNull(schema.OneOf[1].Reference);
            Assert.Equal("SubType2", schema.OneOf[1].Reference.Id);
            Assert.Equal(new[] { "Property2", "BaseProperty" }, schemaRepository.Schemas["SubType2"].Properties.Keys);
        }
示例#5
0
        public override OpenApiSchema CreateDefinitionSchema(Type type, SchemaRepository schemaRepository)
        {
            if (!(_contractResolver.ResolveContract(type) is JsonDictionaryContract jsonDictionaryContract))
            {
                throw new InvalidOperationException($"Type {type} does not resolve to a JsonDictionaryContract");
            }

            var keyType   = jsonDictionaryContract.DictionaryKeyType ?? typeof(object);
            var valueType = jsonDictionaryContract.DictionaryValueType ?? typeof(object);

            OpenApiSchema schema;

            if (keyType.IsEnum)
            {
                // This is a special case where we can include named properties based on the enum values
                schema = new OpenApiSchema
                {
                    Type       = "object",
                    Properties = keyType.GetEnumNames()
                                 .ToDictionary(
                        name => name,
                        name => _schemaGenerator.GenerateSchema(valueType, schemaRepository)
                        )
                };
            }
            else
            {
                schema = new OpenApiSchema
                {
                    Type = "object",
                    AdditionalPropertiesAllowed = true,
                    AdditionalProperties        = _schemaGenerator.GenerateSchema(valueType, schemaRepository)
                };
            }

            schema.Nullable = (_serializerSettings.NullValueHandling == NullValueHandling.Include);

            return(schema);
        }
示例#6
0
        public async Task CreateClient()
        {
            // arrange
            var serializer = new IdSerializer();
            var schema     = new Schema(Guid.NewGuid(), "abc", "def");
            await SchemaRepository.AddSchemaAsync(schema);

            string schemaId = serializer.Serialize("Schema", schema.Id);

            // act
            IExecutionResult result = await Executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"mutation($schemaId: ID! $name: String! $description: String) {
                            createClient(input: {
                                schemaId: $schemaId
                                name: $name
                                description: $description
                            })
                            {
                                schema {
                                    name
                                    description
                                }
                                client {
                                    name
                                    description
                                }
                            }
                        }")
                .SetVariableValue("schemaId", schemaId)
                .SetVariableValue("name", "client_abc")
                .SetVariableValue("description", "client_def")
                .Create());

            // assert
            result.MatchSnapshot();
        }
示例#7
0
        public void GenerateSchema_HonorsJsonPropertyAnnotations()
        {
            var schemaRepository = new SchemaRepository();

            var referenceSchema = Subject().GenerateSchema(typeof(JsonPropertyAnnotatedType), schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.Equal(
                new[]
            {
                //"StringWithJsonIgnore",
                "string-with-json-property-name",
                "IntWithRequiredDefault",
                "NullableIntWithRequiredDefault",
                "StringWithRequiredDefault",
                "StringWithRequiredDisallowNull",
                "StringWithRequiredAlways",
                "StringWithRequiredAllowNull"
            },
                schema.Properties.Keys.ToArray());

            Assert.Equal(
                new[]
            {
                "StringWithRequiredAllowNull",
                "StringWithRequiredAlways"
            },
                schema.Required.ToArray());

            Assert.True(schema.Properties["string-with-json-property-name"].Nullable);
            Assert.False(schema.Properties["IntWithRequiredDefault"].Nullable);
            Assert.True(schema.Properties["NullableIntWithRequiredDefault"].Nullable);
            Assert.True(schema.Properties["StringWithRequiredDefault"].Nullable);
            Assert.False(schema.Properties["StringWithRequiredDisallowNull"].Nullable);
            Assert.False(schema.Properties["StringWithRequiredAlways"].Nullable);
            Assert.True(schema.Properties["StringWithRequiredAllowNull"].Nullable);
        }
        public override OpenApiSchema CreateDefinitionSchema(Type type, SchemaRepository schemaRepository)
        {
            var jsonContract = _contractResolver.ResolveContract(type);

            var stringEnumConverter = (jsonContract.Converter as StringEnumConverter)
                                      ?? _serializerSettings.Converters.OfType <StringEnumConverter>().FirstOrDefault();

            // Temporary shim to support obsolete config options
            if (stringEnumConverter == null && _generatorOptions.DescribeAllEnumsAsStrings)
            {
                stringEnumConverter = new StringEnumConverter(_generatorOptions.DescribeStringEnumsInCamelCase);
            }

            var schema = (stringEnumConverter != null)
                ? EnumTypeMap[typeof(string)]()
                : EnumTypeMap[type.GetEnumUnderlyingType()]();

            if (stringEnumConverter != null)
            {
                schema.Enum = type.GetMembers(BindingFlags.Public | BindingFlags.Static)
                              .Select(member =>
                {
                    var memberAttribute = member.GetCustomAttributes <EnumMemberAttribute>().FirstOrDefault();
                    var stringValue     = GetConvertedEnumName(stringEnumConverter, (memberAttribute?.Value ?? member.Name), (memberAttribute?.Value != null));
                    return(OpenApiAnyFactory.CreateFor(schema, stringValue));
                })
                              .ToList();
            }
            else
            {
                schema.Enum = type.GetEnumValues()
                              .Cast <object>()
                              .Select(value => OpenApiAnyFactory.CreateFor(schema, value))
                              .ToList();
            }

            return(schema);
        }
示例#9
0
        public async Task GetSchemaVersionsById()
        {
            // arrange
            var serializer = new IdSerializer();
            var schema     = new Schema(Guid.NewGuid(), "abc", "def");
            await SchemaRepository.AddSchemaAsync(schema);

            var schemaVersion = new SchemaVersion(
                Guid.NewGuid(), schema.Id, "abc", DocumentHash.FromSourceText("def"),
                Array.Empty <Tag>(), DateTime.UnixEpoch);
            await SchemaRepository.AddSchemaVersionAsync(schemaVersion);

            string id = serializer.Serialize("SchemaVersion", schemaVersion.Id);

            IFileContainer container = await Storage.CreateContainerAsync(
                schemaVersion.Id.ToString("N", CultureInfo.InvariantCulture));

            byte[] buffer = Encoding.UTF8.GetBytes("SourceTextAbc");
            await container.CreateFileAsync("schema.graphql", buffer, 0, buffer.Length);

            // act
            IExecutionResult result = await Executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"query($ids: [ID!]!) {
                            schemaVersionsById(ids: $ids) {
                                id
                                sourceText
                            }
                        }")
                .SetVariableValue("ids", new[] { id })
                .Create());

            // assert
            result.MatchSnapshot(o =>
                                 o.Assert(fo =>
                                          Assert.Equal(id, fo.Field <string>("Data.schemaVersionsById[0].id"))));
        }
        public void GenerateSchema_SubTypeAttributes()
        {
            var subject = Subject(configureGenerator: c =>
            {
                c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: false);
            });

            var schemaRepository = new SchemaRepository();

            var schema = subject.GenerateSchema(typeof(BaseDiscriminatorType), schemaRepository);

            // The base type schema
            Assert.NotNull(schema.Reference);
            var baseSchema = schemaRepository.Schemas[schema.Reference.Id];

            Assert.Equal("object", baseSchema.Type);
            Assert.Equal(new[] { "type", "baseProperty" }, baseSchema.Properties.Keys);

            // The first sub type schema
            var subType1Schema = schemaRepository.Schemas["SubType1"];

            Assert.Equal("object", subType1Schema.Type);
            Assert.NotNull(subType1Schema.AllOf);
            Assert.Equal(1, subType1Schema.AllOf.Count);
            Assert.NotNull(subType1Schema.AllOf[0].Reference);
            Assert.Equal(schema.Reference.Id, subType1Schema.AllOf[0].Reference.Id);
            Assert.Equal(new[] { "property1" }, subType1Schema.Properties.Keys);

            // The second sub type schema
            var subType2Schema = schemaRepository.Schemas["SubType2"];

            Assert.Equal("object", subType2Schema.Type);
            Assert.NotNull(subType2Schema.AllOf);
            Assert.Equal(1, subType2Schema.AllOf.Count);
            Assert.NotNull(subType2Schema.AllOf[0].Reference);
            Assert.Equal(schema.Reference.Id, subType2Schema.AllOf[0].Reference.Id);
            Assert.Equal(new[] { "property2" }, subType2Schema.Properties.Keys);
        }
        private OpenApiSchema CreatePropertySchema(
            JsonProperty jsonProperty,
            IEnumerable <object> customAttributes,
            Required required,
            SchemaRepository schemaRepository)
        {
            var typeSchema = _schemaGenerator.GenerateSchema(jsonProperty.PropertyType, schemaRepository);

            // If it's a referenced/shared schema, "extend" it using allOf so that contextual metadata (e.g. property attributes) can be applied
            var propertySchema = (typeSchema.Reference != null)
                ? new OpenApiSchema {
                AllOf = new[] { typeSchema }
            }
                : typeSchema;

            propertySchema.ReadOnly  = jsonProperty.Readable && !jsonProperty.Writable;
            propertySchema.WriteOnly = !jsonProperty.Readable && jsonProperty.Writable;
            propertySchema.Nullable  = (required == Required.Default || required == Required.AllowNull) && jsonProperty.PropertyType.IsReferenceOrNullableType();

            propertySchema.ApplyCustomAttributes(customAttributes);

            return(propertySchema);
        }
示例#12
0
        private OpenApiPaths GetOpenApiPaths(RpcRouteMetaData metaData, SchemaRepository schemaRepository)
        {
            OpenApiPaths paths = new OpenApiPaths();

            List <UniqueMethod> uniqueMethods = this.GetUniqueKeyMethodPairs(metaData);

            foreach (UniqueMethod method in uniqueMethods)
            {
                string           operationKey = method.UniqueUrl.Replace("/", "_").Replace("#", "|");
                OpenApiOperation operation    = this.GetOpenApiOperation(operationKey, method.Info, schemaRepository);

                var pathItem = new OpenApiPathItem()
                {
                    Operations = new Dictionary <OperationType, OpenApiOperation>()
                    {
                        [OperationType.Post] = operation
                    }
                };
                paths.Add(method.UniqueUrl, pathItem);
            }

            return(paths);
        }
示例#13
0
        public static OpenApiSchema GenerateSchemaForValidator <T>(
            this SchemaRepository schemaRepository,
            IValidator <T> validator,
            SchemaGenerationOptions?schemaGenerationOptions    = null,
            SchemaGenerationSettings?schemaGenerationSettings  = null,
            Action <JsonSerializerOptions>?configureSerializer = null)
        {
            SchemaGenerator schemaGenerator = CreateSchemaGenerator(
                new [] { validator },
                schemaGenerationOptions: schemaGenerationOptions,
                schemaGenerationSettings: schemaGenerationSettings,
                configureSerializer: configureSerializer);

            OpenApiSchema schema = schemaGenerator
                                   .GenerateSchema(typeof(T), schemaRepository);

            if (schema.Reference?.Id != null)
            {
                schema = schemaRepository.Schemas[schema.Reference.Id];
            }

            return(schema);
        }
        public OpenApiSchema GenerateSchema(
            Type type,
            SchemaRepository schemaRepository,
            MemberInfo memberInfo       = null,
            ParameterInfo parameterInfo = null)
        {
            if (type.IsConstructedGenericType && Delta.IsDelta(type))
            {
                var deltaTpe = type.GetGenericArguments()[0];
                var result   = this.defaultSchemaGenerator.GenerateSchema(deltaTpe, schemaRepository, memberInfo, parameterInfo);
                return(result);
            }

            if (typeof(MultiUploadedFileModel).IsAssignableFrom(type))
            {
                var formType = typeof(IFormFile);
                var result   = this.defaultSchemaGenerator.GenerateSchema(formType, schemaRepository, memberInfo, parameterInfo);
                result.Format = nameof(MultiUploadedFileModel);
                return(result);
            }

            return(this.defaultSchemaGenerator.GenerateSchema(type, schemaRepository, memberInfo, parameterInfo));
        }
示例#15
0
        public async void TestUpdateAsync()
        {
            var options = new DbContextOptionsBuilder <ApplicationDbContext>()
                          .UseInMemoryDatabase(databaseName: "SchemaDatabase")
                          .Options;

            var dbContext = new ApplicationDbContext(options);
            var repo      = new SchemaRepository(dbContext);
            var newJson   = "{id: 234}";
            // Act
            var newSchema = await repo.CreateAsync(new Schema()
            {
                SavedDate = DateTime.Now, SchemaJson = "{id: 123}"
            });

            var id = newSchema.Id;

            newSchema.SchemaJson = newJson;
            var result = await repo.UpdateAsync(id, newSchema);

            // Assert
            Assert.True(result.SchemaJson == newJson);
        }
        public void GenerateSchema_SupportsOption_UseAllOfForInheritance()
        {
            var subject = Subject(
                configureGenerator: c => c.UseAllOfForInheritance = true
                );
            var schemaRepository = new SchemaRepository();

            var referenceSchema = subject.GenerateSchema(typeof(SubType1), schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.Equal("object", schema.Type);
            Assert.Equal(new[] { "Property1" }, schema.Properties.Keys);
            Assert.NotNull(schema.AllOf);
            Assert.Equal(1, schema.AllOf.Count);
            Assert.NotNull(schema.AllOf[0].Reference);
            Assert.Equal("BaseType", schema.AllOf[0].Reference.Id);
            // The base type schema
            var baseTypeSchema = schemaRepository.Schemas[schema.AllOf[0].Reference.Id];

            Assert.Equal("object", baseTypeSchema.Type);
            Assert.Equal(new[] { "BaseProperty" }, baseTypeSchema.Properties.Keys);
        }
        private bool TryGetDiscriminatorFor(
            DataContract dataContract,
            SchemaRepository schemaRepository,
            IEnumerable <DataContract> knownTypesDataContracts,
            ParameterInfo parameterInfo,
            out OpenApiDiscriminator discriminator)
        {
            discriminator = null;

            var discriminatorName = _generatorOptions.DiscriminatorNameSelector(dataContract.UnderlyingType)
                                    ?? dataContract.ObjectTypeNameProperty;

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

            discriminator = new OpenApiDiscriminator
            {
                PropertyName = discriminatorName
            };

            foreach (var knownTypeDataContract in knownTypesDataContracts)
            {
                var discriminatorValue = _generatorOptions.DiscriminatorValueSelector(knownTypeDataContract.UnderlyingType)
                                         ?? knownTypeDataContract.ObjectTypeNameValue;

                if (discriminatorValue == null)
                {
                    continue;
                }

                discriminator.Mapping.Add(discriminatorValue, GenerateConcreteSchema(knownTypeDataContract, schemaRepository, parameterInfo).Reference.ReferenceV3);
            }

            return(true);
        }
示例#18
0
        public async Task UpdateSchema_DuplicateName()
        {
            // arrange
            var serializer = new IdSerializer();
            var schemaA    = new Schema(Guid.NewGuid(), "abc", "def");
            var schemaB    = new Schema(Guid.NewGuid(), "def", "ghi");
            await SchemaRepository.AddSchemaAsync(schemaA);

            await SchemaRepository.AddSchemaAsync(schemaB);

            string id = serializer.Serialize("Schema", schemaA.Id);

            // act
            IExecutionResult result = await Executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"mutation($id: ID!) {
                            updateSchema(input: {
                                id: $id
                                name: ""def""
                                description: ""def2""
                                clientMutationId: ""ghi"" }) {
                                schema {
                                    id
                                    name
                                    description
                                }
                                clientMutationId
                            }
                        }")
                .SetVariableValue("id", id)
                .Create());


            // assert
            result.MatchSnapshot();
        }
示例#19
0
        public OpenApiSchema GenerateSchema(
            Type type,
            SchemaRepository schemaRepository,
            MemberInfo memberInfo       = null,
            ParameterInfo parameterInfo = null)
        {
            var schema = GenerateSchemaForType(type, parameterInfo, schemaRepository);

            if (memberInfo != null)
            {
                ApplyMemberMetadata(schema, type, memberInfo);
            }
            else if (parameterInfo != null)
            {
                ApplyParameterMetadata(schema, type, parameterInfo);
            }

            if (schema.Reference == null)
            {
                ApplyFilters(schema, type, schemaRepository, memberInfo, parameterInfo);
            }

            return(schema);
        }
示例#20
0
        public void TestInitialize()
        {
            _operation = new OpenApiOperation
            {
                Parameters = new List <OpenApiParameter>(_inputApiParameters.Select(
                                                             param => new OpenApiParameter
                {
                    Name = param.Name,
                    In   = param.Location
                }))
            };
            var method = FunctionMethodTestSource.GetMethodInfo();

            _schemaRegistry   = A.Fake <ISchemaGenerator>();
            _schemaRepository = new SchemaRepository();
            var apiDescription = new ApiDescription();

            foreach (var inputApiParameter in _inputApiParameters.Where(param => param.Location == ParameterLocation.Path))
            {
                var parameterDescription = new ApiParameterDescription
                {
                    Name = inputApiParameter.Name,
                    Type = inputApiParameter.Type
                };
                apiDescription.ParameterDescriptions.Add(parameterDescription);
            }

            _context = new OperationFilterContext(apiDescription, _schemaRegistry, _schemaRepository, method);
            A.CallTo(() => _schemaRegistry.GenerateSchema(A <Type> ._, _schemaRepository, A <MemberInfo> ._, A <ParameterInfo> ._))
            .ReturnsLazily((Type type, SchemaRepository repository, MemberInfo memberInfo, ParameterInfo parameterInfo) =>
                           new OpenApiSchema
            {
                Type = type.Name
            });
            _sut = new HttpFunctionPathParameterTypeFilter();
        }
 private OpenApiSchema CreateDictionarySchema(DataContract dataContract, SchemaRepository schemaRepository)
 {
     if (dataContract.DictionaryKeys != null)
     {
         // This is a special case where the set of key values is known (e.g. if the key type is an enum)
         return(new OpenApiSchema
         {
             Type = "object",
             Properties = dataContract.DictionaryKeys.ToDictionary(
                 name => name,
                 name => GenerateSchema(dataContract.DictionaryValueType, schemaRepository)),
             AdditionalPropertiesAllowed = false,
         });
     }
     else
     {
         return(new OpenApiSchema
         {
             Type = "object",
             AdditionalPropertiesAllowed = true,
             AdditionalProperties = GenerateSchema(dataContract.DictionaryValueType, schemaRepository)
         });
     }
 }
示例#22
0
        public void GenerateSchema_HonorsSerializerSetting_StringEnumConverter(
            bool camelCaseText,
            string[] expectedEnumAsJson,
            string expectedDefaultAsJson)
        {
            var subject = Subject(
                configureGenerator: c => { c.UseInlineDefinitionsForEnums = true; },
                configureSerializer: c =>
            {
                var stringEnumConverter = (camelCaseText) ? new StringEnumConverter(new CamelCaseNamingStrategy(), false) : new StringEnumConverter();
                c.Converters.Add(stringEnumConverter);
            }
                );
            var schemaRepository = new SchemaRepository();

            var referenceSchema = subject.GenerateSchema(typeof(TypeWithDefaultAttributeOnEnum), schemaRepository);

            var schema         = schemaRepository.Schemas[referenceSchema.Reference.Id];
            var propertySchema = schema.Properties[nameof(TypeWithDefaultAttributeOnEnum.EnumWithDefault)];

            Assert.Equal("string", propertySchema.Type);
            Assert.Equal(expectedEnumAsJson, propertySchema.Enum.Select(openApiAny => openApiAny.ToJson()));
            Assert.Equal(expectedDefaultAsJson, propertySchema.Default.ToJson());
        }
示例#23
0
        public void GenerateSchema_SetsValidationProperties_IfComplexTypeHasValidationAttributes(Type type)
        {
            var schemaRepository = new SchemaRepository();

            var referenceSchema = Subject().GenerateSchema(type, schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.Equal("credit-card", schema.Properties["StringWithDataTypeCreditCard"].Format);
            Assert.Equal(1, schema.Properties["StringWithMinMaxLength"].MinLength);
            Assert.Equal(3, schema.Properties["StringWithMinMaxLength"].MaxLength);
            Assert.Equal(1, schema.Properties["ArrayWithMinMaxLength"].MinItems);
            Assert.Equal(3, schema.Properties["ArrayWithMinMaxLength"].MaxItems);
            Assert.Equal(1, schema.Properties["IntWithRange"].Minimum);
            Assert.Equal(10, schema.Properties["IntWithRange"].Maximum);
            Assert.Equal("^[3-6]?\\d{12,15}$", schema.Properties["StringWithRegularExpression"].Pattern);
            Assert.Equal(5, schema.Properties["StringWithStringLength"].MinLength);
            Assert.Equal(10, schema.Properties["StringWithStringLength"].MaxLength);
            Assert.Equal(1, schema.Properties["StringWithRequired"].MinLength);
            Assert.False(schema.Properties["StringWithRequired"].Nullable);
            Assert.False(schema.Properties["StringWithRequiredAllowEmptyTrue"].Nullable);
            Assert.Null(schema.Properties["StringWithRequiredAllowEmptyTrue"].MinLength);
            Assert.Equal(new[] { "StringWithRequired", "StringWithRequiredAllowEmptyTrue" }, schema.Required.ToArray());
        }
        public void GenerateSchema_HonorsSerializerAttributes_JsonPropertyNameAndJsonIgnore()
        {
            var schemaRepository = new SchemaRepository();

            var referenceSchema = Subject().GenerateSchema(typeof(JsonPropertyAnnotatedType), schemaRepository);

            var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];

            Assert.Equal(
                new[]
            {
                //"StringWithJsonIgnore",
                "string-with-json-property-name",
                "IntProperty",
                "NullableIntProperty"
            },
                schema.Properties.Keys.ToArray());

            Assert.Empty(schema.Required);

            Assert.True(schema.Properties["string-with-json-property-name"].Nullable);
            Assert.False(schema.Properties["IntProperty"].Nullable);
            Assert.True(schema.Properties["NullableIntProperty"].Nullable);
        }
示例#25
0
        public void GenerateSchema_EnumDefaultValue_HonorsParameterInfoDefaults(
            bool useInlineDefinitions,
            bool camelCaseText,
            string expectedValue)
        {
            var subject = Subject(
                configureGenerator: c =>
            {
                c.UseInlineDefinitionsForEnums     = useInlineDefinitions;
                c.UseAllOfToExtendReferenceSchemas = !useInlineDefinitions;
            },
                configureSerializer: c => { c.Converters.Add(new JsonStringEnumConverter(namingPolicy: (camelCaseText ? JsonNamingPolicy.CamelCase : null), true)); }
                );
            var schemaRepository = new SchemaRepository();

            var parameterInfo = typeof(FakeControllerWithActionWithParamDefaults)
                                .GetMethod(nameof(FakeControllerWithActionWithParamDefaults.ActionWithEnumParamDefaultValue))
                                .GetParameters()[0];

            var schema = subject.GenerateSchema(typeof(IntEnum), schemaRepository, parameterInfo: parameterInfo);

            Assert.Null(schema.Reference);

            if (useInlineDefinitions)
            {
                Assert.NotNull(schema.Type);
            }
            else
            {
                Assert.Null(schema.Type);
            }

            Assert.Equal(useInlineDefinitions ? 0 : 1, schema.AllOf.Count);

            Assert.Equal(expectedValue, ((OpenApiString)schema.Default).Value);
        }
示例#26
0
        private OpenApiSchema GeneratePropertySchema(
            JsonProperty jsonProperty,
            IEnumerable <object> customAttributes,
            Required required,
            SchemaRepository schemaRepository)
        {
            var propertySchema = _schemaGenerator.GenerateSchema(jsonProperty.PropertyType, schemaRepository);

            // If it's NOT a reference schema, apply contextual metadata (i.e. from MemberInfo)
            if (propertySchema.Reference == null)
            {
                propertySchema.ReadOnly  = jsonProperty.Readable && !jsonProperty.Writable;
                propertySchema.WriteOnly = !jsonProperty.Readable && jsonProperty.Writable;

                if (required == Required.Always || required == Required.DisallowNull)
                {
                    propertySchema.Nullable = false;
                }

                propertySchema.ApplyCustomAttributes(customAttributes);
            }

            return(propertySchema);
        }
示例#27
0
 IDictionary <string, OpenApiMediaType> GenerateContentType(string mimeType, Type type, SchemaRepository repository)
 {
     return(new Dictionary <string, OpenApiMediaType>
     {
         [mimeType] = new OpenApiMediaType {
             Schema = _schemaGenerator.GenerateSchema(type, repository)
         }
     });
 }
示例#28
0
        private OpenApiSchema GenerateSchemaForType(Type type, ParameterInfo parameterInfo, SchemaRepository schemaRepository)
        {
            if (TryGetCustomMapping(type, out var mapping))
            {
                return(mapping());
            }

            if (type.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult)))
            {
                return(new OpenApiSchema {
                    Type = "string", Format = "binary"
                });
            }

            if (_generatorOptions.GeneratePolymorphicSchemas)
            {
                var knownSubTypes = _generatorOptions.SubTypesResolver(type);
                if (knownSubTypes.Any())
                {
                    return(GeneratePolymorphicSchema(knownSubTypes, schemaRepository));
                }
            }

            var dataContract = _dataContractResolver.GetDataContractForType(type);

            var shouldBeReferenced =
                // regular object
                (dataContract.DataType == DataType.Object && dataContract.Properties != null && !dataContract.UnderlyingType.IsDictionary()) ||
                // dictionary-based AND self-referencing
                (dataContract.DataType == DataType.Object && dataContract.AdditionalPropertiesType == dataContract.UnderlyingType) ||
                // array-based AND self-referencing
                (dataContract.DataType == DataType.Array && dataContract.ArrayItemType == dataContract.UnderlyingType) ||
                // enum-based AND opted-out of inline
                (dataContract.EnumValues != null && !_generatorOptions.UseInlineDefinitionsForEnums);

            return((shouldBeReferenced)
                ? GenerateReferencedSchema(dataContract, parameterInfo, schemaRepository)
                : GenerateInlineSchema(dataContract, parameterInfo, schemaRepository));
        }
示例#29
0
        private OpenApiSchema GeneratePropertySchema(DataProperty serializerMember, ParameterInfo parameterInfo, SchemaRepository schemaRepository)
        {
            var schema = GenerateSchemaForType(serializerMember.MemberType, parameterInfo, schemaRepository);

            if (serializerMember.MemberInfo != null)
            {
                ApplyMemberMetadata(schema, serializerMember.MemberType, serializerMember.MemberInfo);
            }

            if (schema.Reference == null)
            {
                schema.Nullable  = serializerMember.IsNullable && schema.Nullable;
                schema.ReadOnly  = serializerMember.IsReadOnly;
                schema.WriteOnly = serializerMember.IsWriteOnly;

                ApplyFilters(schema, serializerMember.MemberType, schemaRepository, serializerMember.MemberInfo);
            }

            return(schema);
        }
示例#30
0
        private OpenApiSchema GenerateObjectSchema(DataContract dataContract, ParameterInfo parameterInfo, SchemaRepository schemaRepository)
        {
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>(),
                AdditionalPropertiesAllowed = false
            };

            // If it's a baseType with known subTypes, add the discriminator property
            if (_generatorOptions.GeneratePolymorphicSchemas && _generatorOptions.SubTypesResolver(dataContract.UnderlyingType).Any())
            {
                var discriminatorName = _generatorOptions.DiscriminatorSelector(dataContract.UnderlyingType);

                if (!schema.Properties.ContainsKey(discriminatorName))
                {
                    schema.Properties.Add(discriminatorName, new OpenApiSchema {
                        Type = "string"
                    });
                }

                schema.Required.Add(discriminatorName);
                schema.Discriminator = new OpenApiDiscriminator {
                    PropertyName = discriminatorName
                };
            }

            foreach (var dataProperty in dataContract.Properties ?? Enumerable.Empty <DataProperty>())
            {
                var customAttributes = dataProperty.MemberInfo?.GetInlineOrMetadataTypeAttributes() ?? Enumerable.Empty <object>();

                if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any())
                {
                    continue;
                }

                schema.Properties[dataProperty.Name] = GeneratePropertySchema(dataProperty, parameterInfo, schemaRepository);

                if (dataProperty.IsRequired)
                {
                    schema.Required.Add(dataProperty.Name);
                }
            }

            if (dataContract.AdditionalPropertiesType != null)
            {
                schema.AdditionalPropertiesAllowed = true;
                schema.AdditionalProperties        = GenerateSchema(dataContract.AdditionalPropertiesType, schemaRepository);
            }

            // If it's a known subType, reference the baseType for inheritied properties
            if (
                _generatorOptions.GeneratePolymorphicSchemas &&
                (dataContract.UnderlyingType.BaseType != null) &&
                _generatorOptions.SubTypesResolver(dataContract.UnderlyingType.BaseType).Contains(dataContract.UnderlyingType))
            {
                var basedataContract    = _dataContractResolver.GetDataContractForType(dataContract.UnderlyingType.BaseType);
                var baseSchemaReference = GenerateReferencedSchema(basedataContract, parameterInfo, schemaRepository);

                var baseSchema = schemaRepository.Schemas[baseSchemaReference.Reference.Id];
                foreach (var basePropertyName in baseSchema.Properties.Keys)
                {
                    schema.Properties.Remove(basePropertyName);
                }

                return(new OpenApiSchema
                {
                    AllOf = new List <OpenApiSchema> {
                        baseSchemaReference, schema
                    }
                });
            }

            return(schema);
        }