Write one test for multiple requests - c#

I have a json from OpenApi that have all Http requests from my project, it looks like that:
{
"openapi": "3.0.1",
"info": {
"title": "TestApi",
"version": "1.0"
},
"paths": {
"/api/Test1/test1/{id}": {
"get": {
"tags": [
"Test1"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/api/Test2/test2/{id}": {
"get": {
"tags": [
"Test2"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "Success"
...
I need to create one test that will check only GET requests that all of them return 200. I know how to test one request for needed status code but how to test multiple requests in one test? And how to correctly take them from json?

Related

NJsonSchema C# - Remove $ref fields and replace by the actual structure

I'm using NJsonSchema to convert a normal Json to Schema.
However, NJsonSchema returns the Schema with $ref fields, but I want to have the actual structure.
For example:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Property1": {
"$ref": "#/definitions/Property1"
},
"Property2": {
"$ref": "#/definitions/Property2"
},
"Property3": {
"type": "array",
"items": {
"$ref": "#/definitions/Property3"
}
},
"Property4": {
"type": "array",
"items": {
"$ref": "#/definitions/Property4"
}
}
},
"definitions": {
"Property1": {
"type": "object",
"properties": {
"Property1_1": {
"type": "string"
},
"Property1_2": {
"type": "boolean"
},
"Property1_3": {
"type": "integer"
},
"Property1_4": {
"type": "integer"
}
}
},
"Property2": {
"type": "object",
"properties": {
"Property2_1": {
"$ref": "#/definitions/Property2_1"
},
"Property2_2": {
"$ref": "#/definitions/Property2_2"
}
}
},
"Property2_1": {
"type": "object",
"properties": {
"Property2_1_1": {
"type": "array",
"items": {
"$ref": "#/definitions/Property2_1_1"
}
},
"Property2_1_2": {
"type": "array",
"items": {
"$ref": "#/definitions/Property2_1_2"
}
},
"Property2_1_3": {
"type": "array",
"items": {
"$ref": "#/definitions/Property2_1_3"
}
},
"Property2_1_4": {
"type": "array",
"items": {
"$ref": "#/definitions/Property2_1_4"
}
}
}
},
"Property2_1_1": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
},
"Property2_1_2": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
},
"Property2_1_3": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
}
}
},
"Property2_1_4": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
}
}
},
"Property2_2": {
"type": "object",
"properties": {
"dtm_file_name": {
"type": "string"
},
"dtm_file_name_ext": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
},
"Property3": {
"type": "object",
"properties": {
"offset": {
"type": "integer"
},
"value": {
"type": "string"
}
}
},
"Property4": {
"type": "object",
"properties": {
"attr_name": {
"type": "string"
},
"offset": {
"type": "integer"
}
}
}
}
}
Got the above JSON using:
JsonSchema bodySchema = JsonSchema.FromSampleJson(jsonStr);
string schemaStr = bodySchema.ToJson();
How can I remove these references and replace to the actual structures?
Such as:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Property1": {
"type": "object",
"properties": {
"Property1_1": {
"type": "string"
},
"Property1_2": {
"type": "boolean"
},
"Property1_3": {
"type": "integer"
},
"Property1_4": {
"type": "integer"
}
}
},
"Property2": {
"type": "object",
"properties": {
"Property2_1": {
"type": "object",
"properties": {
"Property2_1_1": {
"type": "array",
"items": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
}
},
"Property2_1_2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
}
},
"Property2_1_3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
}
}
}
},
"Property2_1_4": {
"type": "array",
"items": {
"type": "object",
"properties": {
"filename": {
"type": "string"
},
"interface": {
"type": "string"
}
}
}
}
}
},
"Property2_2": {
"type": "object",
"properties": {
"dtm_file_name": {
"type": "string"
},
"dtm_file_name_ext": {
"type": "string"
},
"_Comment": {
"type": "string"
}
}
}
}
},
"Property3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"offset": {
"type": "integer"
},
"value": {
"type": "string"
}
}
}
},
"Property4": {
"type": "array",
"items": {
"type": "object",
"properties": {
"attr_name": {
"type": "string"
},
"offset": {
"type": "integer"
}
}
}
}
}
}
Is there any method that does that inside NJsonSchema or some other way?
Regards,
Thiago

NjsonSchema Validation If Property1 is equal to Something then require Property2

I seem to not be able to get const or enum working as part of an if-then-else JSON schema validation.
They seem to be interchangeable when 1 validation value is concerned. (Reference)
Here is my JSON schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Test_Schema",
"description": "A schema for validating a test object",
"type": "object",
"additionalProperties": false,
"properties": {
"GeneralData": {
"type": "object",
"description": "Advsor and admin customer information",
"properties": {
"Name": {
"type": [ "string", "null" ],
"description": "Customer's advisor name"
},
"Age": {
"type": [ "string", "null" ],
"description": "Customer's advisor email"
},
"Location": {
"type": [ "string", "null" ],
"description": "The advisor's manager email'"
}
},
"required": [ "Name", "Location", "Age" ]
},
"ClientData": {
"type": "object",
"description": "Customer's information",
"additionalProperties": false,
"properties": {
"Title": {
"type": [ "string", "null" ]
},
"Forename": {
"type": [ "string", "null" ]
},
"Surname": {
"type": [ "string" ]
}
},
"required": [ "Title" ],
"if": {
"properties": {
"Forename": { "enum": [ "Soameonea" ] }
},
"required": [ "Forename" ]
},
"then": { "required": [ "Surname" ] },
"else": false
}
}
}
If Forename = "Someone" I want Surname to be required.
Here is my jsonObject after serialization:
{
"GeneralData": {
"Name": "Not Relevant",
"Age": "Not Relevant",
"Location": "Not Relevant"
},
"ClientData": {
"Title": "SomeTitle",
"Forename": "Someone",
"Surname": null
}
}
Validation code:
internal void ValidateDataObjectOnSchema()
{
var dataObject = PopulateDataObject();
var json = JsonConvert.SerializeObject(dataObject);
var result = GetSchema().Validate(json);
var errors = result.Select(x =>
{
return new Errors() { Title = x.Property, Description = x.Schema.Description };
});
var i = errors;
}
internal JsonSchema GetSchema()
{
return JsonSchema.FromFileAsync("Test/testSchema.json").Result;
}
Right now it still requires Surname, even though the enum Soameonea != Someone and I only require Title. <== Issue1
In the JSON schema if I set "Surname":{"type":["string","null]} then the error disappears and still I don't get the error if I then change the if condition for the Forename enum to "Someone". <== Issue 2
I cannot get a different validation output if I replace Enum with Const, So if I can get one to work I'm sure the other will follow.
I've found several answers to this question (Answer 1), I try to implement the same thing and for some reason, it fails in my case.
What am I missing?
In the JSON schema if I set "Surname":{"type":["string","null]} then the error disappears
A property with a null value still has a value. If you want to say that the property value must not only exist, but not be null, then add "type": "string" to your then condition.
Update:
As #Relequestial mentioned in one of the comments it seems NJson Schema only supports up to Draft 04, this is why if-then-else did not work and implication should be used instead. Below is my solution with an alternative package.
The same code and json work with the package Newtonsoft.Json.Schema (Reference)
Code:
internal void ValidateDataObjectOnSchemaWithNewtonSoftJson()
{
var dataObject = PopulateDataObject();
var settings = new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
};
var jsonDataObjectString = JsonConvert.SerializeObject(dataObject, settings);
JObject jsonDataObject = JObject.Parse(jsonDataObjectString);
var jsonSchemaFile = File.ReadAllText("Test/testSchema.json");
var schema = JSchema.Parse(jsonSchemaFile);
;
IList<ValidationError> messages;
var result = jsonDataObject.IsValid(schema, out messages);
var errors = GetReadableResult(result, messages);
}
private List<Errors> GetReadableResult(bool result, IList<ValidationError> messages)
{
var errors = new List<Errors>();
if (!result)
{
foreach (var error in messages)
{
if (error.ChildErrors.Count > 0)
{
errors.Add(
new Errors()
{
Path = error.ChildErrors.FirstOrDefault()?.Path,
Kind = error.ChildErrors.FirstOrDefault()?.Message
});
}
else
{
errors.Add(new Errors()
{
Path = error.Path,
Kind = error.Message
});
}
}
}
return errors;
}
JsonSchema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Test_Schema",
"description": "A schema for validating a test object",
"type": "object",
"additionalProperties": false,
"properties": {
"GeneralData": {
"type": "object",
"description": "Advsor and admin customer information",
"properties": {
"Name": {
"type": [ "string", "null" ],
"description": "Customer's advisor name"
},
"Age": {
"type": [ "string", "null" ],
"description": "Customer's advisor email"
},
"Location": {
"type": [ "string", "null" ],
"description": "The advisor's manager email'"
}
},
"required": [ "Name", "Location", "Age" ]
},
"ClientData": {
"type": "object",
"description": "Customer's information",
"additionalProperties": false,
"properties": {
"Title": {
"type": [ "string", "null" ]
},
"Forename": {
"type": "string"
},
"Surname": {
"type": [ "string" ]
}
},
"required": [ "Title" ],
"if": {
"properties": {
"Forename": { "enum": [ "Someone" ] }
},
"required": [ "Forename" ]
},
"then": { "required": [ "Surname" ] },
"else": {}
}
}
}
The only addition would be to make the GetReadableResult recursive for Errors which have multiple child items.

C# deleting json field

{
"from": 0,
"query": {
"bool": {
"must": [
{
"query_string": {
"analyze_wildcard": true,
"default_operator": "and",
"fields": [
"applicationCd"
],
"query": "$applicationCd"
}
},
{
"query_string": {
"analyze_wildcard": true,
"default_operator": "and",
"fields": [
"entityStatusDesc"
],
"query": "$entityStatusDesc"
}
},
{
"query_string": {
"analyze_wildcard": true,
"default_operator": "and",
"fields": [
"stepUserName"
],
"query": "$stepUserName"
}
},
{
"match": {
"model": {
"query": "instance"
}
}
}
]
}
},
"size": 10,
"sort": [
{
"instanceId": {
"missing": "_last",
"order": "desc"
}
}
]
}
I have json file and i just want to delete entire block inside must area due to given field name(applicationCd,EntityStatusDesc,StepUsername) .For example if given field is applicationCd i want to delete that field entirely and my json should look like this.I will be grateful if anyone could help me.Thanks.
{
"from": 0,
"query": {
"bool": {
"must": [
{
//deleted part
"query_string": {
"analyze_wildcard": true,
"default_operator": "and",
"fields": [
"entityStatusDesc"
],
"query": "$entityStatusDesc"
}
},
rest of the code is same

Merge Multiple JSON and Multiple level of Group By in C#

I'm trying to merge multiple JSON files which has the same type of data inside them and fetch the merged data from those JSONs. For example below are two JSON files.
JSON 1
[
{
"Name": "Sample1",
"Data": [
{
"Name": "Sample1 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["278924"]
}
]
}
]
},
{
"Name": "Sample2",
"Data": [
{
"Name": "Sample2 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["278378"]
},
{
"Name": "YYY",
"ID": ["278289"]
}
]
}
]
}
]
JSON 2
[
{
"Name": "Sample1",
"Data": [
{
"Name": "Sample1 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["357896"]
}
]
}
]
},
{
"Name": "Sample2",
"Data": [
{
"Name": "Sample2 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["356842"]
},
{
"Name": "YYY",
"ID": ["357123"]
}
]
}
]
}
]
I'm expecting the output to be in the below format.
[
{
"Name": "Sample1",
"Data": [
{
"Name": "Sample1 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["278924, 357896"]
}
]
}
]
},
{
"Name": "Sample2",
"Data": [
{
"Name": "Sample2 Sub1",
"Data": [
{
"Name": "XXX",
"ID": ["278378,356842"]
},
{
"Name": "YYY",
"ID": ["278289,357123"]
}
]
}
]
}
]
I'm not sure where to start this. I tried groupby for multiple level but couldn't able to fetch the result in expected format.
Any help would be appreciated.

Deploy IIS Website with CloudFormation template

I have a Visual Studio (C#) deployment package (.zip) that I have pushed up to my S3 storage.
I want to run my CloudFormation script and have it create an instance of an IIS server (I have the script for this) and then deploy the Visual Studio web site to it from the S3 storage.
I'm looking for an example of the temple json that would do that
I have a template that does something similar to what you are looking for. Below is a template that I use. It may be more than you need, because it has an auto scaling group, but it will get you started. Basically, you need the IAM user to interact with cloud formation. The script in the UserData starts cf-init, which does the stuff in the metadata section.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Autoscaling for .net Web application.",
"Parameters": {
"InstanceType": {
"Description": "WebServer EC2 instance type",
"Type": "String",
"Default": "m1.small",
"AllowedValues": [
"t1.micro",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m2.xlarge",
"m2.2xlarge",
"m2.4xlarge",
"c1.medium",
"c1.xlarge",
"cc1.4xlarge",
"cc2.8xlarge",
"cg1.4xlarge"
],
"ConstraintDescription": "Must be a valid EC2 instance type."
},
"IamInstanceProfile": {
"Description": "Name of IAM Profile that will be used by instances to access AWS Services",
"Type": "String",
"Default": "YourProfileName"
},
"KeyName": {
"Description": "The EC2 Key Pair to allow access to the instances",
"Default": "yourkeypair",
"Type": "String"
},
"SpotPriceBid": {
"Description": "Max bid price of spot instances",
"Type": "String",
"Default": ".06"
},
"DeployS3Bucket": {
"Description": "The S3 Bucket where deploy files are stored",
"Type": "String",
"Default": "ApplicationBucket"
},
"DeployWebS3Key": {
"Description": "The zip file that holds the website",
"Type": "String",
"Default": "Application.zip"
},
"DNSHostedZone": {
"Type": "String",
"Default": "example.com.",
"AllowedPattern": "^[\\w\\.]*\\.$",
"ConstraintDescription": "DNSDomain must end with '.'"
},
"DNSSubDomain": {
"Type": "String",
"Default": "yoursubdomain"
}
},
"Mappings": {
"RegionToAMIMap": {
"us-east-1": {
"AMI": "ami-1234567"
}
}
},
"Resources": {
"IAMUser": {
"Type": "AWS::IAM::User",
"Properties": {
"Path": "/",
"Policies": [{
"PolicyName": "webuser",
"PolicyDocument": {
"Statement": [{
"Sid": "Stmt1353842250430",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::HelgaDogWeb*/*"
]
}, {
"Sid": "Stmt1353842327065",
"Action": [
"cloudformation:DescribeStackResource"
],
"Effect": "Allow",
"Resource": [
"*"
]
}
]
}
}
]
}
},
"IAMUserAccessKey": {
"Type": "AWS::IAM::AccessKey",
"Properties": {
"UserName": {
"Ref": "IAMUser"
}
}
},
"WebSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable Access From Elastic Load Balancer.",
"SecurityGroupIngress": [{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"SourceSecurityGroupOwnerId": {
"Fn::GetAtt": [
"WebLoadBalancer",
"SourceSecurityGroup.OwnerAlias"
]
},
"SourceSecurityGroupName": {
"Fn::GetAtt": [
"WebLoadBalancer",
"SourceSecurityGroup.GroupName"
]
}
}, {
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"SourceSecurityGroupOwnerId": {
"Fn::GetAtt": [
"WebLoadBalancer",
"SourceSecurityGroup.OwnerAlias"
]
},
"SourceSecurityGroupName": {
"Fn::GetAtt": [
"WebLoadBalancer",
"SourceSecurityGroup.GroupName"
]
}
}
]
}
},
"WebLoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties": {
"Listeners": [{
"InstancePort": "443",
"InstanceProtocol": "HTTPS",
"LoadBalancerPort": "443",
"Protocol": "HTTPS",
"SSLCertificateId": "arn:aws:iam::123456789101:server-certificate/example"
}
],
"AvailabilityZones": {
"Fn::GetAZs": ""
},
"HealthCheck": {
"HealthyThreshold": "3",
"Interval": "30",
"Target": "HTTP:80/healthcheck.aspx",
"Timeout": 8,
"UnhealthyThreshold": "2"
}
}
},
"WebAsSpotLaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"sources": {
"C:\\inetpub\\wwwroot": {
"Fn::Join": [
"/",
[
"http://s3.amazonaws.com", {
"Ref": "DeployS3Bucket"
}, {
"Ref": "DeployWebS3Key"
}
]
]
}
},
"commands": {
"1-set-appPool-identity": {
"command": "C:\\Windows\\System32\\inetsrv\\appcmd set config /section:applicationPools /[name='DefaultAppPool'].processModel.identityType:LocalSystem",
"waitAfterCompletion": "0"
},
"2-add-http-binding": {
"command": "C:\\Windows\\System32\\inetsrv\\appcmd set site /site.name:\"Default Web Site\" /+bindings.[protocol='http',bindingInformation='*:80:']",
"waitAfterCompletion": "0"
}
}
}
},
"AWS::CloudFormation::Authentication": {
"S3AccessCreds": {
"type": "S3",
"accessKeyId": {
"Ref": "IAMUserAccessKey"
},
"secretKey": {
"Fn::GetAtt": [
"IAMUserAccessKey",
"SecretAccessKey"
]
},
"buckets": [{
"Ref": "DeployS3Bucket"
}
]
}
}
},
"Properties": {
"KeyName": {
"Ref": "KeyName"
},
"ImageId": {
"Fn::FindInMap": [
"RegionToAMIMap", {
"Ref": "AWS::Region"
},
"AMI"
]
},
"IamInstanceProfile": {
"Ref": "IamInstanceProfile"
},
"SecurityGroups": [{
"Ref": "WebSecurityGroup"
}
],
"InstanceType": {
"Ref": "InstanceType"
},
"SpotPrice": {
"Ref": "SpotPriceBid"
},
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"<script>\n",
"\"C:\\Program Files (x86)\\Amazon\\cfn-bootstrap\\cfn-init.exe\" -v -s ", {
"Ref": "AWS::StackName"
},
" -r WebAsSpotLaunchConfiguration ",
" --access-key ", {
"Ref": "IAMUserAccessKey"
},
" --secret-key ", {
"Fn::GetAtt": [
"IAMUserAccessKey",
"SecretAccessKey"
]
},
"\n",
"</script>"
]
]
}
}
}
},
"WebAsSpotGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"AvailabilityZones": {
"Fn::GetAZs": ""
},
"HealthCheckGracePeriod": "120",
"HealthCheckType": "EC2",
"LaunchConfigurationName": {
"Ref": "WebAsSpotLaunchConfiguration"
},
"LoadBalancerNames": [{
"Ref": "WebLoadBalancer"
}
],
"MaxSize": "20",
"MinSize": "1",
"DesiredCapacity": "1"
}
},
"WebAsSpotScaleUpPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "PercentChangeInCapacity",
"AutoScalingGroupName": {
"Ref": "WebAsSpotGroup"
},
"Cooldown": "420",
"ScalingAdjustment": "200"
}
},
"WebAsSpotScaleDownPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {
"Ref": "WebAsSpotGroup"
},
"Cooldown": "60",
"ScalingAdjustment": "-1"
}
},
"WebAsSpotScaleUpAlarm": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "60",
"EvaluationPeriods": "1",
"Threshold": "75",
"AlarmActions": [{
"Ref": "WebAsSpotScaleUpPolicy"
}
],
"Dimensions": [{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "WebAsSpotGroup"
}
}
],
"ComparisonOperator": "GreaterThanThreshold"
}
},
"WebAsSpotScaleDownAlarm": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "60",
"EvaluationPeriods": "2",
"Threshold": "50",
"AlarmActions": [{
"Ref": "WebAsSpotScaleDownPolicy"
}
],
"Dimensions": [{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "WebAsSpotGroup"
}
}
],
"ComparisonOperator": "LessThanThreshold"
}
},
"DNSRecord": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"HostedZoneName": {
"Ref": "DNSHostedZone"
},
"Comment": "VPN Host. Created by Cloud Formation.",
"Name": {
"Fn::Join": [
".",
[{
"Ref": "DNSSubDomain"
}, {
"Ref": "DNSHostedZone"
}
]
]
},
"Type": "CNAME",
"TTL": "150",
"ResourceRecords": [{
"Fn::GetAtt": [
"WebLoadBalancer",
"CanonicalHostedZoneName"
]
}
]
},
"DependsOn": "WebLoadBalancer"
}
},
"Outputs": {}
}
I havent tried it myself, but this post, on the AWS site, Using Amazon CloudFront with ASP.NET Apps maybe somewhere to start.

Categories