diff --git a/backend/helpers/plural.endpoint.handler.test.ts b/backend/helpers/plural.endpoint.handler.test.ts new file mode 100644 index 0000000..50ce253 --- /dev/null +++ b/backend/helpers/plural.endpoint.handler.test.ts @@ -0,0 +1,34 @@ +import express from 'express'; +import { Request, Response } from 'express'; +import request from 'supertest'; +import { describe, expect } from '@jest/globals'; + +import { pluralEndpointHandler } from './plural.endpoint.handler'; +import { HttpCode } from './constants'; + +const app = express(); +const router = express.Router(); + +router.route('/book').get((req: Request, res: Response) => { + return res.status(HttpCode.OK).send(); +}); + +router.route('*').get((req, res) => { + return pluralEndpointHandler(req, res); +}); + +app.use(router) + +describe('plural endpoint handler', () => { + it('should return 200 when the path does not end with s', async () => { + const response = await request(app).get('/book'); + expect(response.statusCode).toEqual(HttpCode.OK); + }); + + it('should return 404 when the path ends with s', async () => { + const response = await request(app).get('/books'); + expect(response.statusCode).toEqual(HttpCode.NOT_FOUND); + expect(response.body.success).toBe(false); + expect(response.body.message).toBe("Not found. Did you mean to use the singular version of the endpoint, /book?"); + }); +}); \ No newline at end of file diff --git a/backend/helpers/plural.endpoint.handler.ts b/backend/helpers/plural.endpoint.handler.ts new file mode 100644 index 0000000..ed9c26a --- /dev/null +++ b/backend/helpers/plural.endpoint.handler.ts @@ -0,0 +1,13 @@ +import { Request, Response } from 'express'; +import { HttpCode, notFoundResponse } from './constants'; + +export const pluralEndpointHandler = (req: Request, res: Response) => { + if (req.path.toLowerCase().endsWith('s')) { + return res.status(HttpCode.NOT_FOUND).send({ + success: false, + message: `Not found. Did you mean to use the singular version of the endpoint, ${req.path.substring(0, req.path.length - 1)}?` + }); + } + + return res.status(HttpCode.NOT_FOUND).send(notFoundResponse); +}; \ No newline at end of file diff --git a/backend/routes/api.ts b/backend/routes/api.ts index a592c62..754eaf9 100644 --- a/backend/routes/api.ts +++ b/backend/routes/api.ts @@ -1,13 +1,15 @@ import { Router } from 'express';; -import { notFoundResponse, HttpCode } from '../helpers/constants'; import { bookController } from '../controllers/book.api'; import { chapterController } from '../controllers/chapter.api'; import { movieController } from '../controllers/movie.api'; import { characterController } from '../controllers/character.api'; import { quoteController } from '../controllers/quote.api'; + import { errorHandler } from '../middleware/api.errors'; + import { passportHelpers } from '../helpers/passport'; +import { pluralEndpointHandler } from '../helpers/plural.endpoint.handler'; const router = Router(); @@ -29,8 +31,9 @@ router.route('/character/:id/quote').get([passportHelpers.authenticate, characte router.route('/quote').get([passportHelpers.authenticate, quoteController.getQuotes]); router.route('/quote/:id').get([passportHelpers.authenticate, quoteController.getQuote]); router.route('/quotes/random').get([passportHelpers.authenticate, quoteController.getRandomQuote]); -router.route('*').get(async (req, res) => { - return res.status(HttpCode.NOT_FOUND).send(notFoundResponse); + +router.route('*').get((req, res) => { + return pluralEndpointHandler(req, res); }); // global error handler. This should always be the last .use // and after all routes