Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dee3246
refactor: display throwable errors too
RGO230 Jul 2, 2025
115f599
Merge branch '163-modify-500-code-error-response-page' of https://git…
RGO230 Jul 2, 2025
1c7dfcf
refactor: set empty array for not exception errors
RGO230 Jul 3, 2025
fe96b4b
refactor: add empty email exception message to view
RGO230 Jul 9, 2025
241a8f7
fix: remove useless
RGO230 Jul 9, 2025
6624b40
refactor: add defaul unhandled error message
RGO230 Sep 1, 2025
79d523c
refactor: use try catch
RGO230 Sep 11, 2025
66d348a
refactor: use try catch in correct place
RGO230 Sep 12, 2025
c48e7f2
fix: tests
RGO230 Sep 17, 2025
86a3613
refactor: remove useless
RGO230 Sep 17, 2025
2d6f294
style:fix
RGO230 Sep 24, 2025
2baa6e4
refactor: remove generateDataWithExceptionHandling
RGO230 Sep 28, 2025
b8c8e88
style:fix
RGO230 Sep 29, 2025
c779d33
refactor: mock getTraceMethod
RGO230 Oct 6, 2025
b5f1058
fix: make correct trace format
RGO230 Oct 6, 2025
e91f3c7
refactor: make TraceMockTrait
RGO230 Oct 6, 2025
70c3fe8
Merge branch 'master' into 163-modify-500-code-error-response-page
RGO230 Oct 6, 2025
500b9df
style:fix
RGO230 Oct 6, 2025
9cc86e5
style:fix
RGO230 Oct 6, 2025
9bc0e27
style:fix
RGO230 Oct 6, 2025
9435c06
Merge branch '163-modify-500-code-error-response-page' of https://git…
RGO230 Oct 6, 2025
0d5d70e
fix: correct find trace info in response content
RGO230 Oct 7, 2025
99e0fc5
refactor: make tests for github ci env
RGO230 Oct 7, 2025
9868465
fix:tests
RGO230 Oct 7, 2025
33cf5e7
test
RGO230 Oct 8, 2025
dd35456
test
RGO230 Oct 8, 2025
827a160
test
RGO230 Oct 8, 2025
e3205a5
test
RGO230 Oct 8, 2025
bd3182f
test
RGO230 Oct 8, 2025
4f49531
test
RGO230 Oct 8, 2025
ae6c2f3
test
RGO230 Oct 8, 2025
15f9f27
test
RGO230 Oct 8, 2025
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-with-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Execute unit tests via PHPUnit with coverage
run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml
run: php -d zend.exception_ignore_args=0 -d xdebug.collect_params=4 vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- name: Export coverage report
if: ${{ matrix.php-version == '8.4' }}
uses: actions/upload-artifact@v4
Expand Down
5 changes: 5 additions & 0 deletions lang/en/validation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'unhandled_error_message' => 'Documentation file is empty or have bad format',
];
15 changes: 14 additions & 1 deletion resources/views/error.blade.php
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
{{ $message }}
# ❗️ **ERROR** ❗️

## 🚨🚨 {{ $type }} 🚨🚨

---

### **Details:**

{{ $message }}

### **Error place:**

{{ $error_place }}
---
2 changes: 2 additions & 0 deletions src/AutoDocServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public function boot()
{
$this->mergeConfigFrom(__DIR__ . '/../config/auto-doc.php', 'auto-doc');

$this->loadTranslationsFrom(__DIR__ . '/../lang', 'auto-doc');

$this->publishes([
__DIR__ . '/../config/auto-doc.php' => config_path('auto-doc.php'),
], 'config');
Expand Down
76 changes: 55 additions & 21 deletions src/Services/SwaggerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use RonasIT\AutoDoc\Traits\GetDependenciesTrait;
use RonasIT\AutoDoc\Validators\SwaggerSpecValidator;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
use Exception;

/**
Expand Down Expand Up @@ -73,6 +74,10 @@ public function __construct(Container $container)
$this->setDriver();

if (config('app.env') === 'testing') {
// client must enter at least `contact.email` to generate a default `info` block
// otherwise an exception will be called
$this->checkEmail();

$this->container = $container;

$this->security = $this->config['security'];
Expand All @@ -84,6 +89,23 @@ public function __construct(Container $container)

$this->driver->saveProcessTmpData($this->data);
}
} else {
try {
$this->checkEmail();
} catch (EmptyContactEmailException $exception) {
$this->data = $this->generateEmptyData(
$this->config['defaults']['error'],
[
'message' => $exception->getMessage(),
'type' => $exception::class,
'error_place' => $this->getErrorPlace($exception),
],
);

$this->driver->saveProcessTmpData($this->data);

$this->driver->saveData();
}
}
}

Expand Down Expand Up @@ -134,12 +156,6 @@ protected function setDriver()

protected function generateEmptyData(?string $view = null, array $viewData = [], array $license = []): array
{
// client must enter at least `contact.email` to generate a default `info` block
// otherwise an exception will be called
if (!empty($this->config['info']) && !Arr::get($this->config, 'info.contact.email')) {
throw new EmptyContactEmailException();
}

if (empty($view) && !empty($this->config['info'])) {
$view = $this->config['info']['description'];
}
Expand All @@ -165,6 +181,13 @@ protected function generateEmptyData(?string $view = null, array $viewData = [],
return $data;
}

protected function checkEmail(): void
{
if (!empty($this->config['info']) && !Arr::get($this->config, 'info.contact.email')) {
throw new EmptyContactEmailException();
}
}

protected function generateSecurityDefinition(): ?array
{
if (empty($this->security)) {
Expand Down Expand Up @@ -796,18 +819,6 @@ protected function getActionName($uri): string
return Str::camel($action);
}

/**
* @deprecated method is not in use
* @codeCoverageIgnore
*/
protected function saveTempData()
{
$exportFile = Arr::get($this->config, 'files.temporary');
$data = json_encode($this->data);

file_put_contents($exportFile, $data);
}

public function saveProductionData()
{
if (ParallelTesting::token()) {
Expand All @@ -831,8 +842,19 @@ public function getDocFileContent()
$documentation = $this->driver->getDocumentation();

$this->openAPIValidator->validate($documentation);
} catch (Exception $exception) {
return $this->generateEmptyData($this->config['defaults']['error'], ['message' => $exception->getMessage()]);
} catch (Throwable $exception) {
$message = ($exception instanceof Exception)
? $exception->getMessage()
: __('validation.unhandled_error_message');

return $this->generateEmptyData(
$this->config['defaults']['error'],
[
'message' => $message,
'type' => $exception::class,
'error_place' => $this->getErrorPlace($exception),
]
);
}

$additionalDocs = config('auto-doc.additional_paths', []);
Expand All @@ -852,6 +874,18 @@ public function getDocFileContent()
return $documentation;
}

protected function getErrorPlace(Throwable $exception): string
{
$errorPlaceInTrace = Arr::first($exception->getTrace());

$errorPlaceInTrace = implode(', ', Arr::map(
$errorPlaceInTrace,
fn ($value, $key) => $key . '=' . (is_array($value) ? json_encode($value) : $value),
));

return $errorPlaceInTrace;
}

protected function camelCaseToUnderScore($input): string
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
Expand Down Expand Up @@ -973,7 +1007,7 @@ protected function prepareInfo(?string $view = null, array $viewData = [], array
if (!empty($view)) {
$info['description'] = view($view, $viewData)->render();
}

return array_merge($this->config['info'], $info);
}

Expand Down
21 changes: 20 additions & 1 deletion tests/AutoDocControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

use Illuminate\Http\Response;
use phpmock\phpunit\PHPMock;
use RonasIT\AutoDoc\Tests\Support\Traits\TraceMockTrait;

class AutoDocControllerTest extends TestCase
{
use PHPMock;
use PHPMock, TraceMockTrait;

protected static array $documentation;
protected static string $localDriverFilePath;
Expand Down Expand Up @@ -40,6 +41,24 @@ public function testGetJSONDocumentation()
$response->assertJson(self::$documentation);
}

public function testGetJSONWithoutEmailDocumentation()
{
config([
'auto-doc.info.contact.email' => null,
'app.env' => 'development',
]);

$response = $this->json('get', '/auto-doc/documentation');

$response->assertStatus(Response::HTTP_OK);

$content = $response->json();

$this->mockGetTrace($content['info']['description']);

$this->assertEqualsJsonFixture('documentation_without_email', $content);
}

public function testGetJSONDocumentationWithAdditionalPaths()
{
config([
Expand Down
24 changes: 21 additions & 3 deletions tests/SwaggerServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
use RonasIT\AutoDoc\Tests\Support\Traits\SwaggerServiceMockTrait;
use RonasIT\AutoDoc\Tests\Support\Traits\SwaggerServiceTestingTrait;
use stdClass;
use RonasIT\AutoDoc\Tests\Support\Traits\TraceMockTrait;

class SwaggerServiceTest extends TestCase
{
use SwaggerServiceMockTrait, SwaggerServiceTestingTrait;
use SwaggerServiceMockTrait, SwaggerServiceTestingTrait, TraceMockTrait;

public function testConstructorInvalidConfigVersion()
{
Expand Down Expand Up @@ -186,14 +187,17 @@ public static function getConstructorInvalidTmpData(): array
[
'tmpDoc' => 'documentation/invalid_format__missing_local_ref',
'fixture' => 'invalid_format_missing_local_ref.html',
'eight_dot_four_fixture' => 'php_8.4_invalid_format_missing_local_ref.html'
],
[
'tmpDoc' => 'documentation/invalid_format__missing_external_ref',
'fixture' => 'invalid_format_missing_external_ref.html',
'eight_dot_four_fixture' => 'php_8.4_invalid_format_missing_external_ref.html'
],
[
'tmpDoc' => 'documentation/invalid_format__missing_ref_file',
'fixture' => 'invalid_format_missing_ref_file.html',
'eight_dot_four_fixture' => 'php_8.4_invalid_format_missing_ref_file.html'
],
[
'tmpDoc' => 'documentation/invalid_format__invalid_schema_type',
Expand Down Expand Up @@ -223,28 +227,42 @@ public static function getConstructorInvalidTmpData(): array
'tmpDoc' => 'documentation/invalid_format__response__invalid_items',
'fixture' => 'invalid_format_response_invalid_items.html',
],
[
'tmpDoc' => 'documentation/tmp_data_incorrect_documentation_structure_request',
'fixture' => 'invalid_format_incorrect_documentation_structure_request.html',
],
];
}

#[DataProvider('getConstructorInvalidTmpData')]
public function testGetDocFileContentInvalidTmpData(
string $tmpDoc,
string $fixture,
?string $eight_dot_four_fixture = null,
) {
$this->mockDriverGetDocumentation($this->getJsonFixture($tmpDoc));

$content = app(SwaggerService::class)->getDocFileContent();

$this->assertEqualsFixture($fixture, $content['info']['description']);
$this->mockGetTrace($content['info']['description']);

if (!empty($eight_dot_four_fixture)
&& version_compare(PHP_VERSION, '8.4.0', '>=')) {
$this->assertEqualsFixture($eight_dot_four_fixture, $content['info']['description']);
} else {
$this->assertEqualsFixture($fixture, $content['info']['description']);
}

}

public function testEmptyContactEmail()
{
config(['auto-doc.info.contact.email' => null]);

$this->expectException(EmptyContactEmailException::class);
$this->expectExceptionMessage('Please fill the `info.contact.email` field in the app-doc.php config file.');

app(SwaggerService::class);
app(SwaggerService::class)->getDocFileContent();
}

public static function getAddEmptyData(): array
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function assertEqualsJsonFixture(string $fixtureName, $data, bool $export
public function assertEqualsFixture(string $fixtureName, $data, bool $exportMode = false): void
{
if ($exportMode || $this->globalExportMode) {
$this->exportContent($fixtureName, $data);
$this->exportContent($data, $fixtureName);
}

$this->assertEquals($this->getFixture($fixtureName), $data);
Expand Down
90 changes: 0 additions & 90 deletions tests/fixtures/AutoDocControllerTest/documentation__non_json.txt

This file was deleted.

Loading