From 62069f07e0af62b738fd6e2ea473f4a56b2ed932 Mon Sep 17 00:00:00 2001 From: Fernando Isidro Luna Date: Thu, 28 Nov 2024 01:22:10 -0600 Subject: [PATCH] feat: :sparkles: add response status assertions shortcuts --- src/response.ts | 182 ++++++++++++++++++++++++++++++ tests/response/assertions.spec.ts | 66 +++++++++++ 2 files changed, 248 insertions(+) diff --git a/src/response.ts b/src/response.ts index f370843..17e5348 100644 --- a/src/response.ts +++ b/src/response.ts @@ -426,4 +426,186 @@ export class ApiResponse extends Macroable { } ) } + + /** + * Assert that response has an ok (200) status + */ + assertOk() { + this.assertStatus(200) + } + + /** + * Assert that response has a created (201) status + */ + assertCreated() { + this.assertStatus(201) + } + + /** + * Assert that response has an accepted (202) status + */ + assertAccepted() { + this.assertStatus(202) + } + + /** + * Assert that response has a no content (204) status + */ + assertNoContent() { + this.assertStatus(204) + } + + /** + * Assert that response has a moved permanently (301) status + */ + assertMovedPermanently() { + this.assertStatus(301) + } + + /** + * Assert that response has a found (302) status + */ + assertFound() { + this.assertStatus(302) + } + + /** + * Assert that response has a bad request (400) status + */ + assertBadRequest() { + this.assertStatus(400) + } + + /** + * Assert that response has an unauthorized (401) status + */ + assertUnauthorized() { + this.assertStatus(401) + } + + /** + * Assert that response has a payment required (402) status + */ + assertPaymentRequired() { + this.assertStatus(402) + } + + /** + * Assert that response has a forbidden (403) status + */ + assertForbidden() { + this.assertStatus(403) + } + + /** + * Assert that response has a not found (404) status + */ + assertNotFound() { + this.assertStatus(404) + } + + /** + * Assert that response has a method not allowed (405) status + */ + assertMethodNotAllowed() { + this.assertStatus(405) + } + + /** + * Assert that response has a not acceptable (406) status + */ + assertNotAcceptable() { + this.assertStatus(406) + } + + /** + * Assert that response has a request timeout (408) status + */ + assertRequestTimeout() { + this.assertStatus(408) + } + + /** + * Assert that response has a conflict (409) status + */ + assertConflict() { + this.assertStatus(409) + } + + /** + * Assert that response has a gone (410) status + */ + assertGone() { + this.assertStatus(410) + } + + /** + * Assert that response has a length required (411) status + */ + assertLengthRequired() { + this.assertStatus(411) + } + + /** + * Assert that response has a precondition failed (412) status + */ + assertPreconditionFailed() { + this.assertStatus(412) + } + + /** + * Assert that response has a payload too large (413) status + */ + assertPayloadTooLarge() { + this.assertStatus(413) + } + + /** + * Assert that response has a URI too long (414) status + */ + assertURITooLong() { + this.assertStatus(414) + } + + /** + * Assert that response has an unsupported media type (415) status + */ + assertUnsupportedMediaType() { + this.assertStatus(415) + } + + /** + * Assert that response has a range not satisfiable (416) status + */ + assertRangeNotSatisfiable() { + this.assertStatus(416) + } + + /** + * Assert that response has an im a teapot (418) status + */ + assertImATeapot() { + this.assertStatus(418) + } + + /** + * Assert that response has an unprocessable entity (422) status + */ + assertUnprocessableEntity() { + this.assertStatus(422) + } + + /** + * Assert that response has a locked (423) status + */ + assertLocked() { + this.assertStatus(423) + } + + /** + * Assert that response has a too many requests (429) status + */ + assertTooManyRequests() { + this.assertStatus(429) + } } diff --git a/tests/response/assertions.spec.ts b/tests/response/assertions.spec.ts index 43fa370..ed19d37 100644 --- a/tests/response/assertions.spec.ts +++ b/tests/response/assertions.spec.ts @@ -12,6 +12,18 @@ import { test } from '@japa/runner' import { ApiRequest } from '../../src/request.js' import { httpServer } from '../../tests_helpers/index.js' +import { ApiResponse } from '../../src/response.js' + +type ExtractAllowed = Pick< + Base, + { + [Key in keyof Base]: Base[Key] extends Condition + ? Key extends `assert${string}` + ? Key + : never + : never + }[keyof Base] +> test.group('Response | assertions', (group) => { group.each.setup(async () => { @@ -19,6 +31,60 @@ test.group('Response | assertions', (group) => { return () => httpServer.close() }) + test('assert response status { status } shortcut from { method }') + .with< + { + method: NonNullable void>> + status: number + }[] + >([ + { method: 'assertOk', status: 200 }, + { method: 'assertCreated', status: 201 }, + { method: 'assertAccepted', status: 202 }, + { method: 'assertNoContent', status: 204 }, + { method: 'assertMovedPermanently', status: 301 }, + { method: 'assertFound', status: 302 }, + { method: 'assertBadRequest', status: 400 }, + { method: 'assertUnauthorized', status: 401 }, + { method: 'assertPaymentRequired', status: 402 }, + { method: 'assertForbidden', status: 403 }, + { method: 'assertNotFound', status: 404 }, + { method: 'assertMethodNotAllowed', status: 405 }, + { method: 'assertNotAcceptable', status: 406 }, + { method: 'assertRequestTimeout', status: 408 }, + { method: 'assertConflict', status: 409 }, + { method: 'assertGone', status: 410 }, + { method: 'assertLengthRequired', status: 411 }, + { method: 'assertPreconditionFailed', status: 412 }, + { method: 'assertPayloadTooLarge', status: 413 }, + { method: 'assertURITooLong', status: 414 }, + { method: 'assertUnsupportedMediaType', status: 415 }, + { method: 'assertRangeNotSatisfiable', status: 416 }, + { method: 'assertImATeapot', status: 418 }, + { method: 'assertUnprocessableEntity', status: 422 }, + { method: 'assertLocked', status: 423 }, + { method: 'assertTooManyRequests', status: 429 }, + ]) + .run(async ({ assert }, { method, status }) => { + assert.plan(1) + + httpServer.onRequest((_, res) => { + res.statusCode = status + if (status > 300 && status < 303) { + res.setHeader('Location', '/see-this-instead') + } + res.end('handled') + }) + + const request = new ApiRequest( + { baseUrl: httpServer.baseUrl, method: 'GET', endpoint: '/' }, + assert + ) + + const response = await request + response[method]() + }) + test('assert response status', async ({ assert }) => { assert.plan(1)