Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run-tests-laravel-7.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: run-letsts-laravel-7
name: run-tests-laravel-7

on: [push, pull_request]

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![](https://banners.beyondco.de/Laravel%20API%20Response%20Helpers.png?theme=light&packageManager=composer+require&packageName=f9webltd%2Flaravel-api-response-helpers&pattern=brickWall&style=style_1&description=Generate+consistent+API+responses+for+your+Laravel+application&md=1&showWatermark=0&fontSize=100px&images=code)

[![run-tests](https://img.shields.io/github/workflow/status/f9webltd/laravel-api-response-helpers/run-tests?style=flat-square)](https://github.com/f9webltd/laravel-api-response-helpers/actions/workflows/run-tests.yml)
[![run-tests](https://img.shields.io/github/workflow/status/f9webltd/laravel-api-response-helpers/run-tests?style=flat-square)](https://github.com/f9webltd/laravel-api-response-helpers/actions)
[![Packagist Version](https://img.shields.io/packagist/v/f9webltd/laravel-api-response-helpers?style=flat-square)](https://packagist.org/packages/f9webltd/laravel-api-response-helpers)
[![Packagist PHP Version](
https://img.shields.io/packagist/php-v/f9webltd/laravel-api-response-helpers?style=flat-square)](https://packagist.org/packages/f9webltd/laravel-api-response-helpers)
Expand Down
309 changes: 176 additions & 133 deletions tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

namespace F9Web\ApiResponseHelpers\Tests;

use DomainException;
use F9Web\ApiResponseHelpers;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\Response;
use JsonException;
use DomainException;
use Illuminate\Support\Collection;

use function json_encode;

class ResponseTest extends TestCase
{
Expand All @@ -20,141 +23,181 @@ public function setUp(): void
parent::setUp();
}

public function testRespondNotFound(): void
/**
* @dataProvider basicResponsesDataProvider
* @throws JsonException
*/
public function testResponses(string $method, array $args, int $code, array $data): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondNotFound('Ouch!');
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"error":"Ouch!"}', $response->getContent());
self::assertEquals(['error' => 'Ouch!'], $response->getData(true));

$response = $this->service->respondNotFound(new DomainException('Unknown model'));
self::assertJsonStringEqualsJsonString('{"error":"Unknown model"}', $response->getContent());
self::assertEquals(['error' => 'Unknown model'], $response->getData(true));

$response = $this->service->respondNotFound('Ouch!', 'nope');
$response = call_user_func_array([$this->service, $method], $args);
self::assertInstanceOf(JsonResponse::class, $response);
self::assertJsonStringEqualsJsonString('{"nope":"Ouch!"}', $response->getContent());
self::assertEquals(['nope' => 'Ouch!'], $response->getData(true));
}

public function testRespondWithSuccess(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondWithSuccess();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_OK, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"success":true}', $response->getContent());
self::assertEquals(['success' => true], $response->getData(true));

$response = $this->service->respondWithSuccess(['super' => 'response', 'yes' => 123]);
self::assertJsonStringEqualsJsonString('{"super":"response","yes":123}', $response->getContent());
self::assertEquals(['super' => 'response', 'yes' => 123], $response->getData(true));

$response = $this->service->respondWithSuccess(new Collection(['super' => 'response', 'yes' => 123]));
self::assertJsonStringEqualsJsonString('{"super":"response","yes":123}', $response->getContent());
self::assertEquals(['super' => 'response', 'yes' => 123], $response->getData(true));
self::assertEquals($code, $response->getStatusCode());
self::assertEquals($data, $response->getData(true));
self::assertJsonStringEqualsJsonString(json_encode($data, JSON_THROW_ON_ERROR), $response->getContent());
}

public function testRespondOk(): void
public function basicResponsesDataProvider(): array
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondOk('Record updated');
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_OK, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"success":"Record updated"}', $response->getContent());
self::assertEquals(['success' => 'Record updated'], $response->getData(true));
}

public function testRespondUnAuthenticated(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondUnAuthenticated();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"error":"Unauthenticated"}', $response->getContent());
self::assertEquals(['error' => 'Unauthenticated'], $response->getData(true));

/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondUnAuthenticated('Not allowed');
self::assertEquals(['error' => 'Not allowed'], $response->getData(true));
}

public function testRespondForbidden(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondForbidden();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"error":"Forbidden"}', $response->getContent());
self::assertEquals(['error' => 'Forbidden'], $response->getData(true));

/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondForbidden('No way');
self::assertEquals(['error' => 'No way'], $response->getData(true));
}

public function testRespondError(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondError();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"error":"Error"}', $response->getContent());
self::assertEquals(['error' => 'Error'], $response->getData(true));

/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondError('Error ...');
self::assertEquals(['error' => 'Error ...'], $response->getData(true));
}

public function testRespondCreated(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondCreated();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_CREATED, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('[]', $response->getContent());
self::assertEquals([], $response->getData(true));

$response = $this->service->respondCreated([ 'id' => 123, 'title' => 'ABC' ]);
self::assertJsonStringEqualsJsonString('{"id":123,"title":"ABC"}', $response->getContent());
self::assertEquals([ 'id' => 123, 'title' => 'ABC' ], $response->getData(true));

$response = $this->service->respondCreated(new Collection([ 'id' => 123, 'title' => 'ABC' ]));
self::assertJsonStringEqualsJsonString('{"id":123,"title":"ABC"}', $response->getContent());
self::assertEquals([ 'id' => 123, 'title' => 'ABC' ], $response->getData(true));
self::assertEquals(Response::HTTP_CREATED, $response->getStatusCode());
}

public function testRespondFailedValidation(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondFailedValidation('Password is required');
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_UNPROCESSABLE_ENTITY, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"message":"Password is required"}', $response->getContent());
self::assertEquals(['message' => 'Password is required'], $response->getData(true));

/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondFailedValidation(new DomainException('Bad things happening ...'));
self::assertJsonStringEqualsJsonString('{"message":"Bad things happening ..."}', $response->getContent());
self::assertEquals(['message' => 'Bad things happening ...'], $response->getData(true));

/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondFailedValidation('Password is required', 'erm');
self::assertJsonStringEqualsJsonString('{"erm":"Password is required"}', $response->getContent());
self::assertEquals(['erm' => 'Password is required'], $response->getData(true));
}

public function testRespondTeapot(): void
{
/** @var \Illuminate\Http\JsonResponse $response */
$response = $this->service->respondTeapot();
self::assertInstanceOf(JsonResponse::class, $response);
self::assertEquals(Response::HTTP_I_AM_A_TEAPOT, $response->getStatusCode());
self::assertJsonStringEqualsJsonString('{"message":"I\'m a teapot"}', $response->getContent());
self::assertEquals(['message' => 'I\'m a teapot'], $response->getData(true));
return [
'respondNotFound()' => [
'respondNotFound',
['Ouch'],
Response::HTTP_NOT_FOUND,
['error' => 'Ouch'],
],

'respondNotFound() with custom key' => [
'respondNotFound',
['Ouch', 'message'],
Response::HTTP_NOT_FOUND,
['message' => 'Ouch'],
],

'respondNotFound() with exception and custom key' => [
'respondNotFound',
[
new DomainException('Unknown model'),
'message'
],
Response::HTTP_NOT_FOUND,
['message' => 'Unknown model'],
],

'respondWithSuccess(), default response data' => [
'respondWithSuccess',
[],
Response::HTTP_OK,
['success' => true],
],

'respondWithSuccess(), custom response data' => [
'respondWithSuccess',
[['order' => 237]],
Response::HTTP_OK,
['order' => 237],
],

'respondWithSuccess(), nested custom response data' => [
'respondWithSuccess',
[['order' => 237, 'customer' => ['name' => 'Jason Bourne']]],
Response::HTTP_OK,
['order' => 237, 'customer' => ['name' => 'Jason Bourne']],
],

'respondWithSuccess(), collection' => [
'respondWithSuccess',
[new Collection(['invoice' => 23, 'status' => 'pending'])],
Response::HTTP_OK,
['invoice' => 23, 'status' => 'pending'],
],

'respondOk()' => [
'respondOk',
['Order accepted'],
Response::HTTP_OK,
['success' => 'Order accepted'],
],

'respondUnAuthenticated(), default message' => [
'respondUnAuthenticated',
[],
Response::HTTP_UNAUTHORIZED,
['error' => 'Unauthenticated'],
],

'respondUnAuthenticated(), custom message' => [
'respondUnAuthenticated',
['Denied'],
Response::HTTP_UNAUTHORIZED,
['error' => 'Denied'],
],

'respondForbidden(), default message' => [
'respondForbidden',
[],
Response::HTTP_FORBIDDEN,
['error' => 'Forbidden'],
],

'respondForbidden(), custom message' => [
'respondForbidden',
['Disavowed'],
Response::HTTP_FORBIDDEN,
['error' => 'Disavowed'],
],

'respondError(), default message' => [
'respondError',
[],
Response::HTTP_BAD_REQUEST,
['error' => 'Error'],
],

'respondError(), custom message' => [
'respondError',
['Order tampering detected'],
Response::HTTP_BAD_REQUEST,
['error' => 'Order tampering detected'],
],

'respondCreated()' => [
'respondCreated',
[],
Response::HTTP_CREATED,
[],
],

'respondCreated() with response data' => [
'respondCreated',
[['user' => ['name' => 'Jet Li']]],
Response::HTTP_CREATED,
['user' => ['name' => 'Jet Li']],
],

'respondCreated(), with collection as response' => [
'respondCreated',
[new Collection(['invoice' => 23, 'status' => 'pending'])],
Response::HTTP_CREATED,
['invoice' => 23, 'status' => 'pending'],
],

'respondFailedValidation()' => [
'respondFailedValidation',
['An invoice is required'],
Response::HTTP_UNPROCESSABLE_ENTITY,
['message' => 'An invoice is required'],
],

'respondTeapot()' => [
'respondTeapot',
[],
Response::HTTP_I_AM_A_TEAPOT,
['message' => 'I\'m a teapot'],
],

'respondNoContent()' => [
'respondNoContent',
[],
Response::HTTP_NO_CONTENT,
[],
],

// @see https://github.com/f9webltd/laravel-api-response-helpers/issues/5#issuecomment-917418285
'respondNoContent() with data' => [
'respondNoContent',
[['role' => 'manager']],
Response::HTTP_NO_CONTENT,
['role' => 'manager'],
],

// @see https://github.com/f9webltd/laravel-api-response-helpers/issues/5#issuecomment-917418285
'respondNoContent(), with collection as response' => [
'respondNoContent',
[new Collection(['invoice' => 23, 'status' => 'pending'])],
Response::HTTP_NO_CONTENT,
['invoice' => 23, 'status' => 'pending'],
],
];
}
}
}