예제 #1
0
            public async Task <Result> Handle(Command request, CancellationToken cancellationToken)
            {
                var contract = await _db.Contract.SingleAsync(x => x.Id == request.ContractId && x.VersionNumber == request.VersionNumber,
                                                              cancellationToken : cancellationToken);

                return(new Result
                {
                    Contract = SchemaObject.BuildSchemaDictionary(contract.ContractString, NoOp, NoOp)
                });
            }
예제 #2
0
        public List <string> BuildPropertyList(string contractString)
        {
            // For this view, we don't care about the body of the properties (only displaying the name),
            // so it's OK if there's an error parsing the references (handle with NoOp)
            var schema     = SchemaObject.BuildSchemaDictionary(contractString, NoOp, NoOp);
            var properties = new List <string>();

            if (schema.ContainsKey("Contract"))
            {
                properties = schema["Contract"].Properties.Keys.ToList();
            }
            return(properties);
        }
예제 #3
0
            public async Task <Result> Handle(Command request, CancellationToken cancellationToken)
            {
                var contract = await _db.Contract.SingleAsync(x => x.Id == request.ContractId && x.VersionNumber == request.VersionNumber,
                                                              cancellationToken);

                var schemaDictionary = SchemaObject.BuildSchemaDictionary(contract.ContractString, HandleError, HandleError);

                var sampleString = GenerateSampleString(schemaDictionary, schemaDictionary["Contract"].Properties);

                return(new Result
                {
                    SampleData = sampleString
                });
            }
예제 #4
0
        public void ShouldHaveReferenceErrorWhenNoReferencesExist()
        {
            var contractString = @"{
                ""Contract"": {
                    ""type"": ""object"",
                    ""properties"": {
                        ""Id"": {
                            ""$ref"": ""#/Guid""
                        },
                        ""Timestamp"": {
                            ""type"": ""string"",
                            ""format"": ""date-time"",
                        }
                    }
                }
            }";
            var errorFound     = false;

            SchemaObject.BuildSchemaDictionary(contractString, () => errorFound = ErrorFound(), FailTest);
            errorFound.ShouldBe(true);
        }
예제 #5
0
        public MappingProfile()
        {
            CreateMap <Create.Command, Contract>()
            .ForMember(x => x.UpdateInst, opt => opt.Ignore())
            .ForMember(x => x.CreatedDate, opt => opt.Ignore())
            .ForMember(x => x.DisplayOnContractList, opt => opt.Ignore())
            .ForMember(x => x.Type, opt => opt.NullSubstitute(""))
            .ForMember(x => x.Namespace, opt => opt.NullSubstitute(""))
            .ReverseMap();

            CreateMap <Contract, Details.ViewModel>()
            .ForMember(x => x.ContractObject, opt => opt.MapFrom(x => SchemaObject.BuildSchemaDictionary(x.ContractString, NoOp, NoOp)));

            CreateMap <Edit.EditModel, Contract>()
            .ForMember(x => x.CreatedDate, opt => opt.Ignore())
            .ForMember(x => x.Type, opt => opt.NullSubstitute(""))
            .ForMember(x => x.Namespace, opt => opt.NullSubstitute(""))
            .ReverseMap();

            CreateMap <Contract, TestMessage.ViewModel>()
            .ForMember(x => x.ContractId, opt => opt.MapFrom(x => x.Id))
            .ForMember(x => x.ContractDescription, opt => opt.MapFrom(x => x.Description))
            .ForMember(x => x.MessageErrors, opt => opt.Ignore())
            .ForMember(x => x.Warnings, opt => opt.Ignore())
            .ForMember(x => x.TestMessage, opt => opt.Ignore())
            .ForMember(x => x.AllowSubset, opt => opt.Ignore())
            .ForMember(x => x.IsValid, opt => opt.Ignore())
            .ForMember(x => x.DeprecationWarningMessage, opt => opt.Ignore())
            .ForMember(x => x.ContractObject, opt => opt.MapFrom(x => SchemaObject.BuildSchemaDictionary(x.ContractString, NoOp, NoOp)));

            CreateMap <Contract, Index.ViewModel>()
            .ForMember(x => x.ContractProperties, opt => opt.MapFrom(x => BuildPropertyList(x.ContractString)))
            .ForMember(x => x.ContractObject, opt => opt.MapFrom(x => SchemaObject.BuildSchemaDictionary(x.ContractString, NoOp, NoOp)));

            CreateMap <Contract, History.ViewModel>()
            .ForMember(x => x.ContractProperties, opt => opt.MapFrom(x => BuildPropertyList(x.ContractString)))
            .ForMember(x => x.ContractObject, opt => opt.MapFrom(x => SchemaObject.BuildSchemaDictionary(x.ContractString, NoOp, NoOp)));
        }
예제 #6
0
        public static IRuleBuilderInitial <T, string> StringMustBeValidContract <T>(this IRuleBuilder <T, string> ruleBuilder)
        {
            return(ruleBuilder.Custom((contractString, context) =>
            {
                var contractDictionary = new CaseInsensitiveDictionary <SchemaObject>();
                JsonObject jsonObjectDictionary = null;
                try
                {
                    jsonObjectDictionary = (JsonObject)JsonValue.Parse(contractString);
                }
                catch (Exception)
                {
                    context.AddFailure("Contract must be valid JSON.");
                }

                if (jsonObjectDictionary != null)
                {
                    const string refError = "Reference definition not found.";
                    const string contractError = "Contract must be defined as a valid OpenAPI schema.";
                    contractDictionary = SchemaObject.BuildSchemaDictionary(contractString,
                                                                            () => HandleError(context, refError),
                                                                            () => HandleError(context, contractError));
                }

                if (contractDictionary.Count > 0)
                { // At least one schema is defined
                    try
                    {
                        var contractObject = contractDictionary["Contract"];

                        if (string.IsNullOrEmpty(contractObject.Type))
                        {
                            context.AddFailure("Contract object must have a property \"type\" with value \"object\".");
                        }
                        else
                        {
                            if (!CheckDataType(contractObject.Type))
                            {
                                context.AddFailure("Contract does not have a valid type.");
                            }
                        }

                        if (contractObject.Properties.Count == 0)
                        {
                            context.AddFailure("An empty contract cannot be saved.");
                        }
                        else
                        {
                            var idKey = contractObject.Properties.Keys.FirstOrDefault(k => k.EqualsCaseInsensitive("ID"));

                            if (idKey != null)
                            {
                                var idProperty = contractObject.Properties[idKey];

                                if (idProperty.Type != null && !idProperty.Type.Equals(DataType.String.Value) ||
                                    idProperty.Reference != "Guid" ||
                                    contractDictionary["Guid"] == null)
                                {
                                    context.AddFailure("Contract must include a property ID of type Guid.");
                                }
                            }

                            var timestampKey = contractObject.Properties.Keys.FirstOrDefault(k => k.EqualsCaseInsensitive("Timestamp"));

                            if (timestampKey != null)
                            {
                                var timestampProperty = contractObject.Properties[timestampKey];

                                if (timestampProperty.Format == null || !timestampProperty.Format.Equals(Format.DateTime.Value))
                                {
                                    context.AddFailure("The Timestamp property must have a format of date-time.");
                                }
                            }

                            CheckProperties(contractObject.Properties, context);
                        }
                    }
                    catch (Exception)
                    {
                        context.AddFailure("Contract must have a properly defined and formatted schema.");
                    }
                }
            }));
        }
예제 #7
0
        public TestMessageResult Execute(string contract, string message, bool allowSubset = false)
        {
            var schemaDictionary = SchemaObject.BuildSchemaDictionary(contract, HandleReferenceError, HandleFailure);

            if (!_isContractValid)
            {
                var contractInvalidMessage = new TestMessageResult
                {
                    IsMessageValid = false,
                    MessageErrors  = new List <string>()
                    {
                        _contractErrorMessage
                    }
                };
                _isContractValid      = true;
                _contractErrorMessage = "";
                return(contractInvalidMessage);
            }

            if (!TryParseJSON(message, out var messageJson))
            {
                return(new TestMessageResult
                {
                    IsMessageValid = false,
                    MessageErrors = new List <string> {
                        "Message contains invalid JSON."
                    }
                });
            }

            var messageDictionary = JsonConvert.DeserializeObject <CaseInsensitiveDictionary <object> >(messageJson.ToString());

            if (messageDictionary.Count <= 0)
            {
                return new TestMessageResult
                       {
                           IsMessageValid = false,
                           MessageErrors  = new List <string> {
                               "Message contains empty JSON."
                           }
                       }
            }
            ;

            var contractDictionary = schemaDictionary.TryGetValue("Contract", out _)
                ? schemaDictionary["Contract"].Properties
                : null;

            if (contractDictionary != null && _isContractValid)
            {
                TestCases.Clear();

                TestCases.Add(AreAllElementsInMessageContainedInContract(messageDictionary, contractDictionary));
                if (!allowSubset)
                {
                    TestCases.Add(AreAllElementsInContractContainedInMessage(messageDictionary, contractDictionary));
                }
                TestCases.Add(DoAllMessageValuesMatchDataTypes(messageDictionary, contractDictionary, allowSubset));
            }

            return(new TestMessageResult
            {
                IsMessageValid = TestCases.All(x => x.IsMessageValid),
                Warnings = TestCases.SelectMany(x => x.Warnings).ToList(),
                MessageErrors = TestCases.SelectMany(x => x.MessageErrors).ToList()
            });
        }
예제 #8
0
 public void ShouldFindReferencesWhenTheyExist()
 {
     SchemaObject.BuildSchemaDictionary(TestDataGenerator.SampleContractString, FailTest, FailTest);
 }