From e2f4c198e0f75cd0e741a615be780009c468148f Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:45:45 +0200 Subject: [PATCH] Better server side validation --- example/App.tsx | 12 ++++++++++-- example/fetchMock.ts | 33 +++++++++++++++++++++++---------- example/msw.ts | 34 ++++++++++++++++++++++++---------- example/sinon.ts | 24 ++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 22 deletions(-) diff --git a/example/App.tsx b/example/App.tsx index e2999f1..0a91491 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -7,6 +7,8 @@ import { ListGuesser, Resource, ShowGuesser, + required, + AutocompleteInput, } from 'react-admin'; import { QueryClient } from 'react-query'; @@ -51,8 +53,14 @@ import authProvider from './authProvider'; export const BookCreate = () => ( - - + + + + ); diff --git a/example/fetchMock.ts b/example/fetchMock.ts index 89935b0..4fe1cca 100644 --- a/example/fetchMock.ts +++ b/example/fetchMock.ts @@ -19,16 +19,29 @@ export const initializeFetchMock = () => { if (!request.headers?.get('Authorization')) { return new Response(null, { status: 401 }); } - - if ( - context.collection === 'books' && - request.method === 'POST' && - !context.requestJson?.title - ) { - return new Response(null, { - status: 400, - statusText: 'Title is required', - }); + return next(request, context); + }); + restServer.addMiddleware(async (request, context, next) => { + if (context.collection === 'books' && request.method === 'POST') { + if ( + restServer.collections[context.collection].getCount({ + filter: { + title: context.requestJson?.title, + }, + }) > 0 + ) { + throw new Response( + JSON.stringify({ + errors: { + title: 'An article with this title already exists. The title must be unique.', + }, + }), + { + status: 400, + statusText: 'Title is required', + }, + ); + } } return next(request, context); diff --git a/example/msw.ts b/example/msw.ts index 4f1ffd2..bef2b18 100644 --- a/example/msw.ts +++ b/example/msw.ts @@ -12,18 +12,32 @@ const restServer = new MswServer({ restServer.addMiddleware(withDelay(300)); restServer.addMiddleware(async (request, context, next) => { if (!request.headers?.get('Authorization')) { - throw new HttpResponse(null, { status: 401 }); + throw new Response(null, { status: 401 }); } + return next(request, context); +}); - if ( - context.collection === 'books' && - request.method === 'POST' && - !context.requestJson?.title - ) { - throw new HttpResponse(null, { - status: 400, - statusText: 'Title is required', - }); +restServer.addMiddleware(async (request, context, next) => { + if (context.collection === 'books' && request.method === 'POST') { + if ( + restServer.collections[context.collection].getCount({ + filter: { + title: context.requestJson?.title, + }, + }) > 0 + ) { + throw new Response( + JSON.stringify({ + errors: { + title: 'An article with this title already exists. The title must be unique.', + }, + }), + { + status: 400, + statusText: 'Title is required', + }, + ); + } } return next(request, context); diff --git a/example/sinon.ts b/example/sinon.ts index 3f96303..2719334 100644 --- a/example/sinon.ts +++ b/example/sinon.ts @@ -20,6 +20,30 @@ export const initializeSinon = () => { return next(request, context); }); + restServer.addMiddleware((request, context, next) => { + if (context.collection === 'books' && request.method === 'POST') { + if ( + restServer.collections[context.collection].getCount({ + filter: { + title: context.requestJson?.title, + }, + }) > 0 + ) { + request.respond( + 401, + {}, + JSON.stringify({ + errors: { + title: 'An article with this title already exists. The title must be unique.', + }, + }), + ); + } + } + + return next(request, context); + }); + // use sinon.js to monkey-patch XmlHttpRequest const server = sinon.fakeServer.create(); // this is required when doing asynchronous XmlHttpRequest