Files
bruno/packages/bruno-tests/collection/scripting/api/res/jsonBody.bru
sanish chirayath e12b736516 feat: add custom jsonBody Chai assertion + simplify Postman translation (#7299)
* feat: enhance jsonBody translation handling in Postman to Bruno converter

* feat: implement jsonBody assertion for Postman compatibility and enhance translation handling

- Added custom Chai assertion for jsonBody to validate JSON structures, including deep equality and nested properties.
- Updated Postman to Bruno translation logic to utilize the new jsonBody assertion, improving the handling of response validations.
- Enhanced test coverage for jsonBody translations, including positive and negative cases for nested properties and deep equality checks.

* feat: enhance jsonBody assertion translations for Postman compatibility

- Added translations for `pm.response.not.to.have.jsonBody` and `pm.response.to.have.not.jsonBody` to the Postman to Bruno converter.
- Updated tests to cover new translation cases, ensuring proper handling of negation scenarios for JSON body assertions.
- Enhanced existing jsonBody assertion logic to support new translation patterns, improving overall compatibility with Postman syntax.

* feat: add advanced path parsing for jsonBody assertions

- Introduced a new `parsePath` function to handle various property path formats, including dot notation, numeric brackets, and quoted keys.
- Updated the `getNestedValue` function to utilize the new path parsing logic, enhancing the robustness of jsonBody assertions.
- Expanded test cases to cover a wide range of scenarios, including edge cases for bracket notation and keys with special characters.

* docs: add examples for parsePath function in jsonBody assertions

- Enhanced documentation for the `parsePath` function by including examples of various property path formats.
- Updated comments in both `assert-runtime.js` and `test.js` to clarify the handling of dot notation, numeric brackets, and quoted keys.

* fix: improve path handling in assertions for quoted keys

- Updated condition checks in `assert-runtime.js` and `test.js` to ensure proper handling of quoted keys in path parsing.
- Enhanced robustness of the path parsing logic to prevent potential out-of-bounds errors.
2026-04-22 12:59:32 +05:30

221 lines
6.5 KiB
Plaintext

meta {
name: jsonBody
type: http
seq: 9
}
post {
url: {{host}}/api/echo/json
body: json
auth: none
}
body:json {
{
"hello": "bruno",
"data": {
"items": [
{ "name": "first" },
{ "name": "second" }
]
},
"matrix": [[1, 2], [3, 4]],
"tags": ["api", "test"],
"some-key": "hyphenated",
"a.b": "dotted-key",
"nested": {
"x.y": { "z": "deep-dotted" }
},
"it's": "apostrophe-key",
"say \"hi\"": "quoted-key"
}
}
assert {
res.status: eq 200
}
tests {
test("jsonBody() - no args validates JSON body", function() {
const body = res.getBody();
expect(body).to.have.jsonBody();
});
test("jsonBody(object) - deep equality", function() {
const body = res.getBody();
expect(body).to.have.jsonBody({
"hello": "bruno",
"data": {
"items": [
{ "name": "first" },
{ "name": "second" }
]
},
"matrix": [[1, 2], [3, 4]],
"tags": ["api", "test"],
"some-key": "hyphenated",
"a.b": "dotted-key",
"nested": {
"x.y": { "z": "deep-dotted" }
},
"it's": "apostrophe-key",
"say \"hi\"": "quoted-key"
});
});
test("jsonBody(path) - nested property exists", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("hello");
expect(body).to.have.jsonBody("data.items");
});
test("jsonBody(path, value) - nested property equals value", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("hello", "bruno");
});
test("jsonBody with bracket notation", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("data.items[0].name", "first");
});
// --- bracket notation and array access ---
test("bracket notation - access array element returns object", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("data.items[0]", { "name": "first" });
expect(body).to.have.jsonBody("data.items[1]", { "name": "second" });
});
test("bracket notation - access top-level array elements", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("tags[0]", "api");
expect(body).to.have.jsonBody("tags[1]", "test");
});
test("bracket notation - consecutive brackets for nested arrays", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("matrix[0][0]", 1);
expect(body).to.have.jsonBody("matrix[0][1]", 2);
expect(body).to.have.jsonBody("matrix[1][0]", 3);
expect(body).to.have.jsonBody("matrix[1][1]", 4);
});
test("bracket notation - access nested array as whole value", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("matrix[0]", [1, 2]);
expect(body).to.have.jsonBody("matrix[1]", [3, 4]);
});
test("bracket notation - out of bounds index is not found", function() {
const body = res.getBody();
expect(body).to.not.have.jsonBody("tags[5]");
expect(body).to.not.have.jsonBody("data.items[99]");
});
// --- edge cases: string bracket keys and keys with dots ---
test("quoted bracket notation - double quotes for string keys", function() {
const body = res.getBody();
expect(body).to.have.jsonBody('["some-key"]', "hyphenated");
});
test("quoted bracket notation - single quotes for string keys", function() {
const body = res.getBody();
expect(body).to.have.jsonBody("['some-key']", "hyphenated");
});
test("quoted bracket notation - keys containing dots", function() {
const body = res.getBody();
expect(body).to.have.jsonBody('["a.b"]', "dotted-key");
});
test("quoted bracket notation - nested path with dotted keys", function() {
const body = res.getBody();
expect(body).to.have.jsonBody('nested["x.y"].z', "deep-dotted");
});
test("quoted bracket notation - key containing the other quote type", function() {
const body = res.getBody();
// Key is: it's — use double quotes so the single quote is not a delimiter
expect(body).to.have.jsonBody("[\"it's\"]", "apostrophe-key");
});
test("quoted bracket notation - escaped quotes in key", function() {
const body = res.getBody();
// Key is: say "hi" — use escaped double quotes inside double-quoted bracket
expect(body).to.have.jsonBody('["say \\"hi\\""]', "quoted-key");
});
test("to.not.have.jsonBody(path) - negation for missing property", function() {
const body = res.getBody();
expect(body).to.not.have.jsonBody("nonexistent");
});
test("to.not.have.jsonBody(path, value) - negation for wrong value", function() {
const body = res.getBody();
expect(body).to.not.have.jsonBody("hello", "wrong");
});
test("to.not.have.jsonBody(object) - negation for deep inequality", function() {
const body = res.getBody();
expect(body).to.not.have.jsonBody({ "wrong": "data" });
});
// --- not.to.have.jsonBody ---
test("not.to.have.jsonBody(path) - negation for missing property", function() {
const body = res.getBody();
expect(body).not.to.have.jsonBody("nonexistent");
});
test("not.to.have.jsonBody(path, value) - negation for wrong value", function() {
const body = res.getBody();
expect(body).not.to.have.jsonBody("hello", "wrong");
});
test("not.to.have.jsonBody(object) - negation for deep inequality", function() {
const body = res.getBody();
expect(body).not.to.have.jsonBody({ "wrong": "data" });
});
test("not.to.have.jsonBody fails when body matches", function() {
const body = res.getBody();
let failed = false;
try {
expect(body).not.to.have.jsonBody("hello");
} catch (e) {
failed = true;
}
expect(failed).to.be.true;
});
// --- to.have.not.jsonBody ---
test("to.have.not.jsonBody(path) - negation for missing property", function() {
const body = res.getBody();
expect(body).to.have.not.jsonBody("nonexistent");
});
test("to.have.not.jsonBody(path, value) - negation for wrong value", function() {
const body = res.getBody();
expect(body).to.have.not.jsonBody("hello", "wrong");
});
test("to.have.not.jsonBody(object) - negation for deep inequality", function() {
const body = res.getBody();
expect(body).to.have.not.jsonBody({ "wrong": "data" });
});
test("to.have.not.jsonBody fails when body matches", function() {
const body = res.getBody();
let failed = false;
try {
expect(body).to.have.not.jsonBody("hello");
} catch (e) {
failed = true;
}
expect(failed).to.be.true;
});
}