mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
feat: add missing status assertions and .not negation support (#7660)
* feat: add new status assertions and negated variants for response checks - Introduced new status assertions: `pm.response.to.be.info`, `pm.response.to.be.accepted`, `pm.response.to.be.badRequest`, `pm.response.to.be.unauthorized`, `pm.response.to.be.forbidden`, `pm.response.to.be.notFound`, `pm.response.to.be.rateLimited`, and `pm.response.to.be.withoutBody`. - Implemented negated variants for existing assertions, allowing checks like `pm.response.to.not.be.ok` and `pm.response.to.not.be.success`. - Enhanced test coverage to validate the translation of these new assertions and their negated forms in the Postman to Bruno conversion process. * refactor: update response translation for body assertions - Changed the translation logic for `pm.response.to.be.withoutBody` to `pm.response.to.be.withBody`, reflecting the actual body content checks. - Updated corresponding test cases to validate the new assertions and ensure correct translation behavior for body presence checks. - Enhanced negated variants for body assertions to align with the updated logic. * feat: add header transformation methods for Postman to Bruno conversion - Introduced new transformations for `pm.request.headers.prepend`, `pm.request.headers.insert`, and `pm.request.headers.insertAfter` to map to `req.headerList.add`, enhancing header management during the conversion process. - Updated the transformation logic to ensure only the first argument is retained for these methods, aligning with the intended behavior of the header list operations. * refactor: update header transformation logic for Postman to Bruno conversion - Simplified the transformation for `pm.response.to.have.header` and `pm.response.to.not.have.header` to use `res.getHeader` instead of `res.getHeaders`, improving clarity and consistency in the assertions. - Adjusted related test cases to validate the new transformation logic, ensuring accurate translation of header checks in the conversion process. * refactor: update header transformation logic for Postman to Bruno conversion - Enhanced the transformation for `pm.response.to.have.header` and `pm.response.to.not.have.header` to utilize `res.getHeaders()` with lowercased header names, improving consistency and accuracy in header assertions. - Updated related test cases to reflect the new transformation logic, ensuring correct translation of header checks in the conversion process. * feat: add data-driven status assertions for response checks - Introduced a new utility to generate data-driven status assertion entries for `pm.response.to.be.*` checks, including positive and negated variants. - Integrated the new status assertions into the Postman to Bruno translation logic, enhancing the capability to handle various response status checks. - Updated tests to validate the translation of new assertions, ensuring accurate conversion of status checks in the response handling process. * feat: enhance response assertion translations for negated variants - Updated the transformation logic for `pm.response.to.have.*` assertions to include negated variants, allowing for patterns like `pm.response.to.have.not.status`, `pm.response.to.have.not.header`, and `pm.response.to.have.not.body`. - Adjusted related test cases to validate the new translations, ensuring accurate conversion of negated assertions in the response handling process. * refactor: convert status assertion utility to ES module syntax - Changed the export of `buildStatusAssertionEntries` to ES module syntax for better compatibility with modern JavaScript practices. - Updated the import statement in the Postman to Bruno translator to reflect the new export format, ensuring seamless integration of the status assertion utility. * feat: update response body assertion translations to use undefined checks - Modified the transformation logic for `pm.response.to.be.withBody`, `pm.response.to.not.be.withBody`, and `pm.response.to.be.not.withBody` to use an undefined check instead of truthiness, allowing for accurate handling of falsy body values. - Updated related test cases to reflect these changes, ensuring correct translation of body presence assertions in the response handling process.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
const j = require('jscodeshift');
|
||||
|
||||
/**
|
||||
* Generates data-driven status assertion entries for pm.response.to.be.*
|
||||
* Each assertion gets positive, to.not.be, and to.be.not variants.
|
||||
*/
|
||||
export const buildStatusAssertionEntries = () => {
|
||||
const buildStatusTransform = (chain, litArgs) => (path) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier(chain)
|
||||
),
|
||||
litArgs.map((v) => j.literal(v))
|
||||
);
|
||||
};
|
||||
|
||||
// Only replaces the first 'to.' — safe because all chains start with 'to.' and contain no other 'to.'
|
||||
const negateChain = (chain) => chain.replace('to.', 'to.not.');
|
||||
|
||||
const statusAssertions = [
|
||||
// Range-based assertions
|
||||
{ name: 'ok', chain: 'to.be.within', args: [200, 299] },
|
||||
{ name: 'success', chain: 'to.be.within', args: [200, 299] },
|
||||
{ name: 'info', chain: 'to.be.within', args: [100, 199] },
|
||||
{ name: 'redirection', chain: 'to.be.within', args: [300, 399] },
|
||||
{ name: 'clientError', chain: 'to.be.within', args: [400, 499] },
|
||||
{ name: 'serverError', chain: 'to.be.within', args: [500, 599] },
|
||||
{ name: 'error', chain: 'to.be.at.least', args: [400] },
|
||||
// Specific status code assertions
|
||||
{ name: 'accepted', chain: 'to.equal', args: [202] },
|
||||
{ name: 'badRequest', chain: 'to.equal', args: [400] },
|
||||
{ name: 'unauthorized', chain: 'to.equal', args: [401] },
|
||||
{ name: 'forbidden', chain: 'to.equal', args: [403] },
|
||||
{ name: 'notFound', chain: 'to.equal', args: [404] },
|
||||
{ name: 'rateLimited', chain: 'to.equal', args: [429] }
|
||||
];
|
||||
|
||||
const entries = [];
|
||||
|
||||
// Generate positive + negated entries for each status assertion
|
||||
statusAssertions.forEach(({ name, chain, args }) => {
|
||||
entries.push(
|
||||
{ pattern: `pm.response.to.be.${name}`, transform: buildStatusTransform(chain, args) },
|
||||
{ pattern: `pm.response.to.not.be.${name}`, transform: buildStatusTransform(negateChain(chain), args) },
|
||||
{ pattern: `pm.response.to.be.not.${name}`, transform: buildStatusTransform(negateChain(chain), args) }
|
||||
);
|
||||
});
|
||||
|
||||
return entries;
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import sendRequestTransformer from './send-request-transformer';
|
||||
import { getMemberExpressionString } from './ast-utils';
|
||||
const j = require('jscodeshift');
|
||||
const cloneDeep = require('lodash/cloneDeep');
|
||||
import { buildStatusAssertionEntries } from './postman-status-assertions';
|
||||
|
||||
// Simple 1:1 translations for straightforward replacements
|
||||
// TODO: Restore the commented-out translations once the UI update fixes are live.
|
||||
@@ -211,87 +212,60 @@ const complexTransformations = [
|
||||
return j.callExpression(j.identifier('res.getHeader'), path.parent.value.arguments);
|
||||
}
|
||||
},
|
||||
// Handle pm.response.to.have.status
|
||||
{
|
||||
pattern: 'pm.response.to.have.status',
|
||||
// pm.response.to[.not].have.status -> expect(res.getStatus()).to[.not].equal(arg)
|
||||
...['to.have.status', 'to.not.have.status', 'to.have.not.status'].map((pattern) => ({
|
||||
pattern: `pm.response.${pattern}`,
|
||||
transform: (path, j) => {
|
||||
const callExpr = path.parent.value;
|
||||
|
||||
const args = callExpr.arguments;
|
||||
|
||||
// Create: expect(res.getStatus()).to.equal(arg)
|
||||
const negated = pattern.includes('.not.');
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(
|
||||
j.identifier('expect'),
|
||||
[
|
||||
j.callExpression(
|
||||
j.identifier('res.getStatus'),
|
||||
[]
|
||||
)
|
||||
]
|
||||
),
|
||||
j.identifier('to.equal')
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier(negated ? 'to.not.equal' : 'to.equal')
|
||||
),
|
||||
args
|
||||
path.parent.value.arguments
|
||||
);
|
||||
}
|
||||
},
|
||||
})),
|
||||
|
||||
// handle 'pm.response.to.have.header' to expect(res.getHeaders()).to.have.property(args)
|
||||
{
|
||||
pattern: 'pm.response.to.have.header',
|
||||
// pm.response.to[.not].have.header -> expect(res.getHeaders()).to[.not].have.property(args)
|
||||
// Header names are lowercased because axios normalizes response headers to lowercase
|
||||
...['to.have.header', 'to.not.have.header', 'to.have.not.header'].map((pattern) => ({
|
||||
pattern: `pm.response.${pattern}`,
|
||||
transform: (path, j) => {
|
||||
const callExpr = path.parent.value;
|
||||
|
||||
const args = callExpr.arguments;
|
||||
const args = path.parent.value.arguments;
|
||||
const negated = pattern.includes('.not.');
|
||||
|
||||
if (args.length > 0) {
|
||||
// Apply toLowerCase() to the first argument
|
||||
args[0] = j.callExpression(
|
||||
j.memberExpression(
|
||||
args[0],
|
||||
j.identifier('toLowerCase')
|
||||
),
|
||||
j.memberExpression(args[0], j.identifier('toLowerCase')),
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
// Create: expect(res.getHeaders()).to.have.property(args)
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(
|
||||
j.identifier('expect'),
|
||||
[
|
||||
j.callExpression(
|
||||
j.identifier('res.getHeaders'),
|
||||
[]
|
||||
)
|
||||
]
|
||||
),
|
||||
j.identifier('to.have.property')
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getHeaders'), [])]),
|
||||
j.identifier(negated ? 'to.not.have.property' : 'to.have.property')
|
||||
),
|
||||
args
|
||||
);
|
||||
}
|
||||
},
|
||||
// handle pm.response.to.have.body to expect(res.getBody()).to.equal(arg)
|
||||
{
|
||||
pattern: 'pm.response.to.have.body',
|
||||
})),
|
||||
|
||||
// pm.response.to[.not].have.body -> expect(res.getBody()).to[.not].equal(arg)
|
||||
...['to.have.body', 'to.not.have.body', 'to.have.not.body'].map((pattern) => ({
|
||||
pattern: `pm.response.${pattern}`,
|
||||
transform: (path, j) => {
|
||||
const callExpr = path.parent.value;
|
||||
|
||||
const args = callExpr.arguments;
|
||||
|
||||
const negated = pattern.includes('.not.');
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.identifier('res.getBody()')]),
|
||||
j.identifier('to.equal')
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getBody'), [])]),
|
||||
j.identifier(negated ? 'to.not.equal' : 'to.equal')
|
||||
),
|
||||
args
|
||||
path.parent.value.arguments
|
||||
);
|
||||
}
|
||||
},
|
||||
})),
|
||||
|
||||
// Handle pm.execution.setNextRequest(null)
|
||||
{
|
||||
@@ -439,90 +413,6 @@ const complexTransformations = [
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.ok -> expect(res.getStatus()).to.be.within(200, 299)
|
||||
{
|
||||
pattern: 'pm.response.to.be.ok',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.within')
|
||||
),
|
||||
[j.literal(200), j.literal(299)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.success -> expect(res.getStatus()).to.be.within(200, 299)
|
||||
{
|
||||
pattern: 'pm.response.to.be.success',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.within')
|
||||
),
|
||||
[j.literal(200), j.literal(299)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.redirection -> expect(res.getStatus()).to.be.within(300, 399)
|
||||
{
|
||||
pattern: 'pm.response.to.be.redirection',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.within')
|
||||
),
|
||||
[j.literal(300), j.literal(399)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.clientError -> expect(res.getStatus()).to.be.within(400, 499)
|
||||
{
|
||||
pattern: 'pm.response.to.be.clientError',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.within')
|
||||
),
|
||||
[j.literal(400), j.literal(499)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.serverError -> expect(res.getStatus()).to.be.within(500, 599)
|
||||
{
|
||||
pattern: 'pm.response.to.be.serverError',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.within')
|
||||
),
|
||||
[j.literal(500), j.literal(599)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.error -> expect(res.getStatus()).to.be.at.least(400)
|
||||
{
|
||||
pattern: 'pm.response.to.be.error',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getStatus'), [])]),
|
||||
j.identifier('to.be.at.least')
|
||||
),
|
||||
[j.literal(400)]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.have.jsonBody(...) -> expect(res.getBody()).to.have.jsonBody(...)
|
||||
{
|
||||
pattern: 'pm.response.to.have.jsonBody',
|
||||
@@ -655,7 +545,49 @@ const complexTransformations = [
|
||||
const args = callExpr.arguments;
|
||||
return j.callExpression(j.identifier('res.getHeader'), args);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// pm.response.to.be.withBody -> expect(res.getBody()).to.not.equal(undefined)
|
||||
// Uses undefined check instead of truthiness (.to.be.ok) so falsy bodies (false, 0, null) pass correctly
|
||||
{
|
||||
pattern: 'pm.response.to.be.withBody',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getBody'), [])]),
|
||||
j.identifier('to.not.equal')
|
||||
),
|
||||
[j.identifier('undefined')]
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
pattern: 'pm.response.to.not.be.withBody',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getBody'), [])]),
|
||||
j.identifier('to.equal')
|
||||
),
|
||||
[j.identifier('undefined')]
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
pattern: 'pm.response.to.be.not.withBody',
|
||||
transform: (path, j) => {
|
||||
return j.callExpression(
|
||||
j.memberExpression(
|
||||
j.callExpression(j.identifier('expect'), [j.callExpression(j.identifier('res.getBody'), [])]),
|
||||
j.identifier('to.equal')
|
||||
),
|
||||
[j.identifier('undefined')]
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// --- Data-driven status assertions (pm.response.to.be.*) ---
|
||||
...buildStatusAssertionEntries()
|
||||
];
|
||||
|
||||
// Create a map for complex transformations to enable O(1) lookups
|
||||
|
||||
@@ -906,4 +906,299 @@ describe('Response Translation', () => {
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('const json = res.headerList.toJSON();');
|
||||
});
|
||||
|
||||
// --- New status assertions ---
|
||||
|
||||
it('should translate pm.response.to.be.info', () => {
|
||||
const code = 'pm.response.to.be.info;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.be.within(100, 199)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.accepted', () => {
|
||||
const code = 'pm.response.to.be.accepted;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(202)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.badRequest', () => {
|
||||
const code = 'pm.response.to.be.badRequest;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(400)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.unauthorized', () => {
|
||||
const code = 'pm.response.to.be.unauthorized;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(401)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.forbidden', () => {
|
||||
const code = 'pm.response.to.be.forbidden;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(403)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.notFound', () => {
|
||||
const code = 'pm.response.to.be.notFound;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(404)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.rateLimited', () => {
|
||||
const code = 'pm.response.to.be.rateLimited;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(429)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.withBody', () => {
|
||||
const code = 'pm.response.to.be.withBody;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getBody()).to.not.equal(undefined);');
|
||||
});
|
||||
|
||||
it('should translate withBody using undefined check (not truthiness) so falsy bodies work', () => {
|
||||
const code = 'pm.response.to.be.withBody;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('to.not.equal(undefined)');
|
||||
});
|
||||
|
||||
it('should handle new status assertions inside test blocks', () => {
|
||||
const code = `
|
||||
pm.test("Status checks", function() {
|
||||
pm.response.to.be.info;
|
||||
pm.response.to.be.accepted;
|
||||
pm.response.to.be.badRequest;
|
||||
pm.response.to.be.unauthorized;
|
||||
pm.response.to.be.forbidden;
|
||||
pm.response.to.be.notFound;
|
||||
pm.response.to.be.rateLimited;
|
||||
});
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('test("Status checks", function() {');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.be.within(100, 199)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(202)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(400)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(401)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(403)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(404)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.equal(429)');
|
||||
});
|
||||
|
||||
// --- .not negation for to.be.* assertions ---
|
||||
|
||||
it('should translate pm.response.to.not.be.ok', () => {
|
||||
const code = 'pm.response.to.not.be.ok;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(200, 299)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.not.ok (alternate position)', () => {
|
||||
const code = 'pm.response.to.be.not.ok;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(200, 299)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.not.forbidden (alternate position)', () => {
|
||||
const code = 'pm.response.to.be.not.forbidden;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(403)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.not.serverError (alternate position)', () => {
|
||||
const code = 'pm.response.to.be.not.serverError;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(500, 599)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.be.not.withBody (alternate position)', () => {
|
||||
const code = 'pm.response.to.be.not.withBody;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getBody()).to.equal(undefined);');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.success', () => {
|
||||
const code = 'pm.response.to.not.be.success;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(200, 299)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.serverError', () => {
|
||||
const code = 'pm.response.to.not.be.serverError;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(500, 599)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.clientError', () => {
|
||||
const code = 'pm.response.to.not.be.clientError;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(400, 499)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.redirection', () => {
|
||||
const code = 'pm.response.to.not.be.redirection;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(300, 399)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.error', () => {
|
||||
const code = 'pm.response.to.not.be.error;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.at.least(400)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.info', () => {
|
||||
const code = 'pm.response.to.not.be.info;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(100, 199)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.accepted', () => {
|
||||
const code = 'pm.response.to.not.be.accepted;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(202)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.badRequest', () => {
|
||||
const code = 'pm.response.to.not.be.badRequest;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(400)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.unauthorized', () => {
|
||||
const code = 'pm.response.to.not.be.unauthorized;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(401)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.forbidden', () => {
|
||||
const code = 'pm.response.to.not.be.forbidden;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(403)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.notFound', () => {
|
||||
const code = 'pm.response.to.not.be.notFound;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(404)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.rateLimited', () => {
|
||||
const code = 'pm.response.to.not.be.rateLimited;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(429)');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.be.withBody', () => {
|
||||
const code = 'pm.response.to.not.be.withBody;';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getBody()).to.equal(undefined);');
|
||||
});
|
||||
|
||||
it('should handle negated assertions inside test blocks', () => {
|
||||
const code = `
|
||||
pm.test("Response is not a server error", function() {
|
||||
pm.response.to.not.be.serverError;
|
||||
pm.response.to.not.be.clientError;
|
||||
});
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('test("Response is not a server error", function() {');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(500, 599)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(400, 499)');
|
||||
});
|
||||
|
||||
it('should handle mixed positive and negated assertions', () => {
|
||||
const code = `
|
||||
pm.test("Mixed assertions", function() {
|
||||
pm.response.to.be.success;
|
||||
pm.response.to.not.be.serverError;
|
||||
});
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.be.within(200, 299)');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(500, 599)');
|
||||
});
|
||||
|
||||
it('should handle negated assertions with aliases', () => {
|
||||
const code = `
|
||||
const resp = pm.response;
|
||||
resp.to.not.be.serverError;
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.be.within(500, 599)');
|
||||
});
|
||||
|
||||
// --- .not negation for to.have.* assertions ---
|
||||
|
||||
it('should translate pm.response.to.not.have.status', () => {
|
||||
const code = 'pm.response.to.not.have.status(404);';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getStatus()).to.not.equal(404);');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.have.header', () => {
|
||||
const code = 'pm.response.to.not.have.header("X-Error");';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getHeaders()).to.not.have.property("X-Error".toLowerCase());');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.have.header with value', () => {
|
||||
const code = 'pm.response.to.not.have.header("Content-Type", "text/plain");';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getHeaders()).to.not.have.property("Content-Type".toLowerCase(), "text/plain");');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.not.have.body', () => {
|
||||
const code = 'pm.response.to.not.have.body("error");';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getBody()).to.not.equal("error");');
|
||||
});
|
||||
|
||||
// --- to.have.not.* (alternate .not position) ---
|
||||
|
||||
it('should translate pm.response.to.have.not.status (alternate position)', () => {
|
||||
const code = 'pm.response.to.have.not.status(404);';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getStatus()).to.not.equal(404);');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.have.not.header (alternate position)', () => {
|
||||
const code = 'pm.response.to.have.not.header("X-Error");';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getHeaders()).to.not.have.property("X-Error".toLowerCase());');
|
||||
});
|
||||
|
||||
it('should translate pm.response.to.have.not.body (alternate position)', () => {
|
||||
const code = 'pm.response.to.have.not.body("error");';
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe('expect(res.getBody()).to.not.equal("error");');
|
||||
});
|
||||
|
||||
it('should handle negated to.have.* assertions inside test blocks', () => {
|
||||
const code = `
|
||||
pm.test("Negative assertions", function() {
|
||||
pm.response.to.not.have.status(500);
|
||||
pm.response.to.not.have.header("X-Error");
|
||||
pm.response.to.not.have.body("error");
|
||||
});
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toContain('test("Negative assertions", function() {');
|
||||
expect(translatedCode).toContain('expect(res.getStatus()).to.not.equal(500)');
|
||||
expect(translatedCode).toContain('expect(res.getHeaders()).to.not.have.property("X-Error".toLowerCase())');
|
||||
expect(translatedCode).toContain('expect(res.getBody()).to.not.equal("error")');
|
||||
});
|
||||
|
||||
it('should handle negated to.have.status with alias', () => {
|
||||
const code = `
|
||||
const resp = pm.response;
|
||||
resp.to.not.have.status(404);
|
||||
`;
|
||||
const translatedCode = translateCode(code);
|
||||
expect(translatedCode).toBe(`
|
||||
expect(res.getStatus()).to.not.equal(404);
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user