mirror of
https://github.com/usebruno/bruno.git
synced 2025-08-19 04:26:18 +02:00
feat: added schema validation before saving collections to idb
This commit is contained in:
@@ -12,9 +12,9 @@ uid Unique id
|
||||
name collection name
|
||||
items Items (folders and requests)
|
||||
|-uid A unique id
|
||||
|-name Request name
|
||||
|-name Item name
|
||||
|-type Item type (folder, http-request, graphql-request)
|
||||
|-request Request object
|
||||
|-type Request type (http, graphql)
|
||||
|-url Request url
|
||||
|-method Request method
|
||||
|-headers Request headers (array of key-val)
|
||||
|
@@ -9,24 +9,22 @@ const keyValueSchema = Yup.object({
|
||||
enabled: Yup.boolean().defined()
|
||||
}).noUnknown(true).strict();
|
||||
|
||||
const requestTypeSchema = Yup.string().oneOf(['http', 'graphql']).required('type is required');
|
||||
const requestUrlSchema = Yup.string().min(0).max(2048, 'name must be 2048 characters or less').defined();
|
||||
const requestMethodSchema = Yup.string().oneOf(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']).required('method is required');
|
||||
|
||||
const requestBodySchema = Yup.object({
|
||||
mode: Yup.string().oneOf(['none', 'json', 'text', 'xml', 'formUrlEncoded', 'multipartForm']).required('mode is required'),
|
||||
json: Yup.string().max(10240, 'json must be 10240 characters or less'),
|
||||
text: Yup.string().max(10240, 'text must be 10240 characters or less'),
|
||||
xml: Yup.string().max(10240, 'xml must be 10240 characters or less'),
|
||||
formUrlEncoded: keyValueSchema,
|
||||
multipartForm: keyValueSchema,
|
||||
json: Yup.string().max(10240, 'json must be 10240 characters or less').nullable(),
|
||||
text: Yup.string().max(10240, 'text must be 10240 characters or less').nullable(),
|
||||
xml: Yup.string().max(10240, 'xml must be 10240 characters or less').nullable(),
|
||||
formUrlEncoded: Yup.array().of(keyValueSchema).nullable(),
|
||||
multipartForm: Yup.array().of(keyValueSchema).nullable(),
|
||||
}).noUnknown(true).strict();
|
||||
|
||||
// Right now, the request schema is very tightly coupled with http request
|
||||
// As we introduce more request types in the future, we will improve the definition to support
|
||||
// schema structure based on other request type
|
||||
const requestSchema = Yup.object({
|
||||
type: requestTypeSchema,
|
||||
url: requestUrlSchema,
|
||||
method: requestMethodSchema,
|
||||
headers: Yup.array().of(keyValueSchema).required('headers are required'),
|
||||
@@ -36,13 +34,13 @@ const requestSchema = Yup.object({
|
||||
|
||||
const itemSchema = Yup.object({
|
||||
uid: uidSchema,
|
||||
type: Yup.string().oneOf(['request', 'folder']).required('type is required'),
|
||||
type: Yup.string().oneOf(['http-request', 'graphql-request', 'folder']).required('type is required'),
|
||||
name: Yup.string()
|
||||
.min(1, 'name must be atleast 1 characters')
|
||||
.max(50, 'name must be 100 characters or less')
|
||||
.required('name is required'),
|
||||
request: requestSchema.when('type', {
|
||||
is: 'request',
|
||||
is: (type) => ['http-request', 'graphql-request'].includes(type),
|
||||
then: (schema) => schema.required('request is required when item-type is request')
|
||||
}),
|
||||
items: Yup.lazy(() => Yup.array().of(itemSchema))
|
||||
|
@@ -46,9 +46,8 @@ describe('Collection Schema Validation', () => {
|
||||
items: [{
|
||||
uid: uuid(),
|
||||
name: 'Get Countries',
|
||||
type: 'request',
|
||||
type: 'http-request',
|
||||
request: {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [],
|
||||
@@ -95,9 +94,8 @@ describe('Collection Schema Validation', () => {
|
||||
items: [{
|
||||
uid: uuid(),
|
||||
name: 'Get Countries',
|
||||
type: 'request',
|
||||
type: 'http-request',
|
||||
request: {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [],
|
||||
|
@@ -41,11 +41,25 @@ describe('Item Schema Validation', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('item schema must throw an error if request is not present when item-type is request', async () => {
|
||||
it('item schema must throw an error if request is not present when item-type is http-request', async () => {
|
||||
const item = {
|
||||
uid: uuid(),
|
||||
name: 'Get Users',
|
||||
type: 'request'
|
||||
type: 'http-request'
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
expect(itemSchema.validate(item)).rejects.toEqual(
|
||||
validationErrorWithMessages('request is required when item-type is request')
|
||||
)
|
||||
]);
|
||||
});
|
||||
|
||||
it('item schema must throw an error if request is not present when item-type is graphql-request', async () => {
|
||||
const item = {
|
||||
uid: uuid(),
|
||||
name: 'Get Users',
|
||||
type: 'graphql-request'
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
|
@@ -5,7 +5,6 @@ const { requestSchema } = require("./index");
|
||||
describe('Request Schema Validation', () => {
|
||||
it('request schema must validate successfully - simple request', async () => {
|
||||
const request = {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [],
|
||||
@@ -19,28 +18,8 @@ describe('Request Schema Validation', () => {
|
||||
expect(isValid).toBeTruthy();
|
||||
});
|
||||
|
||||
it('request schema must throw an error of type is invalid', async () => {
|
||||
const request = {
|
||||
type: 'http-junk',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [],
|
||||
params: [],
|
||||
body: {
|
||||
mode: 'none'
|
||||
}
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
expect(requestSchema.validate(request)).rejects.toEqual(
|
||||
validationErrorWithMessages('type must be one of the following values: http, graphql')
|
||||
)
|
||||
]);
|
||||
});
|
||||
|
||||
it('request schema must throw an error of method is invalid', async () => {
|
||||
const request = {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET-junk',
|
||||
headers: [],
|
||||
@@ -59,7 +38,6 @@ describe('Request Schema Validation', () => {
|
||||
|
||||
it('request schema must throw an error of header name is missing', async () => {
|
||||
const request = {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [{
|
||||
@@ -83,7 +61,6 @@ describe('Request Schema Validation', () => {
|
||||
|
||||
it('request schema must throw an error of param value is missing', async () => {
|
||||
const request = {
|
||||
type: 'http',
|
||||
url: 'https://restcountries.com/v2/alpha/in',
|
||||
method: 'GET',
|
||||
headers: [],
|
||||
|
@@ -1,5 +1,7 @@
|
||||
const { workspaceSchema} = require("./workspaces");
|
||||
const { workspaceSchema } = require("./workspaces");
|
||||
const { collectionSchema } = require("./collections");
|
||||
|
||||
module.exports = {
|
||||
collectionSchema,
|
||||
workspaceSchema
|
||||
};
|
Reference in New Issue
Block a user