OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)
This commit is contained in:
45
tests/Unit/app/Core/Http/Responses/ImageResponseTest.php
Normal file
45
tests/Unit/app/Core/Http/Responses/ImageResponseTest.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Unit\app\Core\Http\Responses;
|
||||
|
||||
use Leantime\Core\Http\Responses\Contracts\LeantimeResponseInterface;
|
||||
use Leantime\Core\Http\Responses\ImageResponse;
|
||||
use SVG\SVG;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Unit\TestCase;
|
||||
|
||||
/**
|
||||
* Unit tests for the ImageResponse response type used by the domain image controllers
|
||||
* (Users\Controllers\ProfileImage, Projects\Controllers\ProjectImage). It is returned
|
||||
* directly from controllers and converted by Laravel's router via the Responsable contract.
|
||||
*/
|
||||
class ImageResponseTest extends TestCase
|
||||
{
|
||||
use \Codeception\Test\Feature\Stub;
|
||||
|
||||
public function test_it_is_a_leantime_response(): void
|
||||
{
|
||||
$this->assertInstanceOf(LeantimeResponseInterface::class, new ImageResponse('/tmp/x'));
|
||||
}
|
||||
|
||||
public function test_to_response_renders_svg_with_cache_headers(): void
|
||||
{
|
||||
$svg = $this->make(SVG::class, [
|
||||
'toXMLString' => fn () => '<svg></svg>',
|
||||
]);
|
||||
|
||||
$response = (new ImageResponse($svg))->toResponse(null);
|
||||
|
||||
$this->assertSame('<svg></svg>', $response->getContent());
|
||||
$this->assertSame('image/svg+xml', $response->headers->get('Content-type'));
|
||||
$this->assertStringContainsString('max-age=86400', $response->headers->get('Cache-Control'));
|
||||
}
|
||||
|
||||
public function test_to_response_passes_through_an_existing_response(): void
|
||||
{
|
||||
$existing = new Response('already built');
|
||||
|
||||
// An uploaded file is already a built Response; it must be returned untouched.
|
||||
$this->assertSame($existing, (new ImageResponse($existing))->toResponse(null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Unit\app\Core\Http\Responses;
|
||||
|
||||
use Leantime\Core\Exceptions\AuthorizationException;
|
||||
use Leantime\Core\Exceptions\ValidationException;
|
||||
use Leantime\Core\Http\Responses\Contracts\LeantimeResponseInterface;
|
||||
use Leantime\Core\Http\Responses\JsonRpcErrorResponse;
|
||||
use RuntimeException;
|
||||
use Unit\TestCase;
|
||||
|
||||
/**
|
||||
* The JSON-RPC 2.0 error envelope response type and its fromException() bridge — the single
|
||||
* place a thrown exception becomes a client-facing error. Typed Leantime exceptions expose
|
||||
* their own code/message/data; any other throwable is collapsed to a generic server error so
|
||||
* internal detail is never leaked.
|
||||
*/
|
||||
class JsonRpcErrorResponseTest extends TestCase
|
||||
{
|
||||
public function test_it_is_a_leantime_response(): void
|
||||
{
|
||||
$this->assertInstanceOf(LeantimeResponseInterface::class, new JsonRpcErrorResponse(-32000, 'x'));
|
||||
}
|
||||
|
||||
public function test_error_envelope(): void
|
||||
{
|
||||
$response = (new JsonRpcErrorResponse(-32602, 'Invalid params', ['field' => ['bad']], 3))->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame('2.0', $body['jsonrpc']);
|
||||
$this->assertSame(-32602, $body['error']['code']);
|
||||
$this->assertSame('Invalid params', $body['error']['message']);
|
||||
$this->assertSame(['field' => ['bad']], $body['error']['data']);
|
||||
$this->assertSame(3, $body['id']);
|
||||
}
|
||||
|
||||
public function test_from_validation_exception_maps_code_and_field_errors(): void
|
||||
{
|
||||
$errors = ['name' => ['Name is required.']];
|
||||
|
||||
$response = JsonRpcErrorResponse::fromException(ValidationException::withMessages($errors), 5)->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame(-32602, $body['error']['code']);
|
||||
$this->assertSame($errors, $body['error']['data']);
|
||||
$this->assertSame(5, $body['id']);
|
||||
}
|
||||
|
||||
public function test_from_authorization_exception_uses_auth_code(): void
|
||||
{
|
||||
$response = JsonRpcErrorResponse::fromException(new AuthorizationException, 1)->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame(-32001, $body['error']['code']);
|
||||
}
|
||||
|
||||
public function test_unknown_throwable_is_generic_and_does_not_leak(): void
|
||||
{
|
||||
$secret = 'internal-db-dsn-with-password';
|
||||
|
||||
$response = JsonRpcErrorResponse::fromException(new RuntimeException($secret), 9)->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame(-32000, $body['error']['code']);
|
||||
$this->assertSame('Server error', $body['error']['message']);
|
||||
$this->assertNull($body['error']['data']);
|
||||
$this->assertStringNotContainsString($secret, $response->getContent());
|
||||
}
|
||||
}
|
||||
47
tests/Unit/app/Core/Http/Responses/JsonRpcResponseTest.php
Normal file
47
tests/Unit/app/Core/Http/Responses/JsonRpcResponseTest.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Unit\app\Core\Http\Responses;
|
||||
|
||||
use Leantime\Core\Http\Responses\Contracts\LeantimeResponseInterface;
|
||||
use Leantime\Core\Http\Responses\JsonRpcResponse;
|
||||
use Unit\TestCase;
|
||||
|
||||
/**
|
||||
* The JSON-RPC 2.0 success envelope response type. Centralizes the `{jsonrpc, result, id}`
|
||||
* wire format previously inlined in the Jsonrpc controller.
|
||||
*/
|
||||
class JsonRpcResponseTest extends TestCase
|
||||
{
|
||||
public function test_it_is_a_leantime_response(): void
|
||||
{
|
||||
$this->assertInstanceOf(LeantimeResponseInterface::class, new JsonRpcResponse('x', 1));
|
||||
}
|
||||
|
||||
public function test_success_envelope(): void
|
||||
{
|
||||
$response = (new JsonRpcResponse(['ok' => true], 7))->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame('2.0', $body['jsonrpc']);
|
||||
$this->assertSame(['ok' => true], $body['result']);
|
||||
$this->assertSame(7, $body['id']);
|
||||
}
|
||||
|
||||
public function test_scalar_result_and_string_id_pass_through(): void
|
||||
{
|
||||
$response = (new JsonRpcResponse(42, 'abc'))->toResponse(null);
|
||||
$body = json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertSame(42, $body['result']);
|
||||
$this->assertSame('abc', $body['id']);
|
||||
}
|
||||
|
||||
public function test_notification_without_id_returns_empty_200(): void
|
||||
{
|
||||
// A JSON-RPC notification (no id) MUST NOT be responded to.
|
||||
$response = (new JsonRpcResponse('ignored', null))->toResponse(null);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertSame('', $response->getContent());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user