Skip to content

Commit

Permalink
Add basic request body checking
Browse files Browse the repository at this point in the history
We now check the request body to see if content was set. For now only
works with application/json
  • Loading branch information
dachrillz committed Aug 3, 2022
1 parent 4e96414 commit 5c32f84
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 25 deletions.
23 changes: 23 additions & 0 deletions scenarios/simple/checkRequestBody/http.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"log": {
"entries": [
{
"request": {
"method": "GET",
"url": "http://localhost/ping",
"postData": {
"mimeType": "application/json",
"text": "{\"hello\":\"world\"}"
}
},
"response": {
"status": 200,
"content": {
"mimeType": "text/plain",
"text": "{\"hello\":\"world\"}"
}
}
}
]
}
}
23 changes: 23 additions & 0 deletions scenarios/simple/checkRequestBody/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
openapi: 3.0.0
info:
title: Minimal example
version: 0.1.0
servers:
- url: "http://localhost:8000"
paths:
/ping:
get:
requestBody:
description: desc
content:
application/json:
schema:
type: string
responses:
'200':
description: Returns `pong`
content:
text/plain:
schema:
type: string
example: pong
23 changes: 23 additions & 0 deletions scenarios/simple/requestBodyNotDefined/http.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"log": {
"entries": [
{
"request": {
"method": "GET",
"url": "http://localhost/ping",
"postData": {
"mimeType": "application/json",
"text": "{\"hello\":\"world\"}"
}
},
"response": {
"status": 200,
"content": {
"mimeType": "text/plain",
"text": "{\"hello\":\"world\"}"
}
}
}
]
}
}
17 changes: 17 additions & 0 deletions scenarios/simple/requestBodyNotDefined/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
openapi: 3.0.0
info:
title: Minimal example
version: 0.1.0
servers:
- url: "http://localhost:8000"
paths:
/ping:
get:
responses:
'200':
description: Returns `pong`
content:
text/plain:
schema:
type: string
example: pong
18 changes: 5 additions & 13 deletions src/api/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,11 @@ const expected: Root = {
x_x_x_x_results: {
hits: 0,
},
"application/json": {
schema: expect.objectContaining({
type: "array",
items: expect.objectContaining({
properties: expect.objectContaining({
name: {
type: "string",
example: "doggie"
},
}),
}),
}),
},
"application/json": expect.objectContaining({
x_x_x_x_results: {
hits: 0,
},
}),
},
},
"400": {
Expand Down
29 changes: 24 additions & 5 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ const readApi = async (path: string): Promise<a.Root> => {
return api;
};

const getMimeType = (content: a.Content): a.MimeType | undefined => {
if (content["application/json"]) {
return a.newMimeType({
items: Object.keys(content["application/json"].schema).length,
});
}
};

const getContent = (response: a.ApiResponse): a.Content | undefined => {
// We only cover application/json for now
if (!response.content) {
Expand All @@ -15,10 +23,7 @@ const getContent = (response: a.ApiResponse): a.Content | undefined => {
x_x_x_x_results: a.newReportItem(),
};

if (response.content["application/json"]) {
contentToBeReturned["application/json"] =
response.content["application/json"];
}
contentToBeReturned["application/json"] = getMimeType(response.content);

return contentToBeReturned;
};
Expand Down Expand Up @@ -53,6 +58,20 @@ const getParameters = (parameters?: a.Parameter[]) => {
});
};

const getRequestBody = (
requestBody?: a.RequestBody
): a.RequestBody | undefined => {
if (!requestBody) {
return;
}

return {
content: getContent(requestBody),
required: requestBody.required,
x_x_x_x_results: a.newReportItem(),
};
};

const getOperation = (
name: a.HTTPMETHOD,
operation?: a.Operation
Expand All @@ -68,7 +87,7 @@ const getOperation = (
};

operationToBeAdded.parameters = getParameters(operation.parameters);
operationToBeAdded.requestBody; // TODO get request body
operationToBeAdded.requestBody = getRequestBody(operation.requestBody);
operationToBeAdded.responses = getResponses(operation.responses);

return operationToBeAdded;
Expand Down
54 changes: 51 additions & 3 deletions src/api/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export type HTTPMETHOD =
export type ApiError =
| "METHOD NOT FOUND"
| "PATH NOT FOUND"
| "STATUS NOT FOUND";
| "STATUS NOT FOUND"
| "REQUEST BODY NOT FOUND"
| "CONTENT WAS NOT FOUND"
| "BAD MIMETYPE";

export type ReportResult = {
hits: number;
Expand Down Expand Up @@ -122,15 +125,41 @@ export type Parameter = {
x_x_x_x_results: ReportResult;
};

export const newRequestBodyWithError = (error: ApiError): RequestBody => {
return {
required: false,
x_x_x_x_results: newReportItemWithError(error),
};
};

export const newRequestBody = (): RequestBody => {
return {
required: false,
x_x_x_x_results: newReportItem(),
};
};

export type RequestBody = {
required: boolean;
content: Content;
content?: Content;

x_x_x_x_results: ReportResult;
};

export const newContentBody = (): Content => {
return {
x_x_x_x_results: newReportItem(),
};
};

export const newContentBodyWithErrors = (error: ApiError): Content => {
return {
x_x_x_x_results: newReportItemWithError(error),
};
};

export type Content = {
"application/json"?: any;
"application/json"?: MimeType;

x_x_x_x_results: ReportResult;
};
Expand All @@ -153,3 +182,22 @@ export type ApiResponse = {

x_x_x_x_results: ReportResult;
};

export const newMimeTypeWithError = (error: ApiError): MimeType => {
return {
schema: null,
x_x_x_x_results: newReportItemWithError(error),
};
};

export const newMimeType = (schema: any): MimeType => {
return {
schema: schema,
x_x_x_x_results: newReportItem(),
};
};

export type MimeType = {
schema: any;
x_x_x_x_results: ReportResult;
};
75 changes: 73 additions & 2 deletions src/rule/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,84 @@ describe("Test Simple Scenarios", () => {
},
},
],
[
"requestBodyNotDefined",
{
success: false,
apiSubtree: {
"/ping": {
x_name: "/ping",
x_x_x_x_results: {
hits: 0,
},
get: {
responses: {},
x_x_x_x_name: "get",
x_x_x_x_results: {
hits: 0,
},
requestBody: {
required: false,
x_x_x_x_results: {
hits: 0,
error: "REQUEST BODY NOT FOUND",
},
},
},
},
},
},
],
[
"checkRequestBody",
{
success: true,
apiSubtree: {
"/ping": {
x_name: "/ping",
x_x_x_x_results: {
hits: 0,
},
get: {
responses: {
"200": {
x_x_x_x_results: {
hits: 0,
},
},
},
x_x_x_x_name: "get",
x_x_x_x_results: {
hits: 0,
},
requestBody: {
required: false,
x_x_x_x_results: {
hits: 0,
},
content: {
x_x_x_x_results: {
hits: 0,
},
"application/json": {
x_x_x_x_results: {
hits: 0,
},
},
},
},
},
},
},
},
],
];

const scenarios = scenarioNames.map((s) => {
return [`./scenarios/simple/${s[0]}`, s[1]];
});

test.each(scenarios)("Rule Match %#", async (scenario, expected) => {
test.each(scenarios)("Rule Match %s", async (scenario, expected) => {
const httpPath = path.join(scenario as string, "http.json");
const apiPath = path.join(scenario as string, "openapi.yaml");

Expand Down Expand Up @@ -220,7 +291,7 @@ describe("Test HAR Scenarios", () => {
return [`./scenarios/har/${s[0]}`, s[1]];
});

test.each(scenarios)("Rule Match %#", async (scenario, expected) => {
test.each(scenarios)("Rule Match %s", async (scenario, expected) => {
const httpPath = path.join(scenario as string, "http.har");
const apiPath = path.join(scenario as string, "openapi.yaml");

Expand Down
Loading

0 comments on commit 5c32f84

Please sign in to comment.