Skip to content

Commit

Permalink
+ Tests\Feature\App\HelperTest for App\Helper
Browse files Browse the repository at this point in the history
* move variable `$statusCodeAndErrorInfos` out of method `abortAPI()` as public const `ERROR_STATUS_CODE_INFO` @ `App\Helper`
* replace `Collection->toArray()` with faster `->all()` @ `App\Http\PostsQuery\CursorCodec->decodeCursor()`
@ be
  • Loading branch information
n0099 committed Sep 24, 2024
1 parent 00cfa5e commit dc4d69b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 29 deletions.
50 changes: 25 additions & 25 deletions be/app/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,35 +54,35 @@ public static function abortAPIIfNot(int $errorCode, bool $condition): void
}
}

public const array ERROR_STATUS_CODE_INFO = [
// httpStatusCode => [ errorCode => errorInfo ]
400 => [
// 40000 => App\Exceptions\Handler::convertValidationExceptionToResponse()
40001 => '帖子查询类型必须为索引或搜索查询',
40002 => '搜索查询必须指定查询贴吧',
40003 => '部分查询参数与查询帖子类型要求不匹配',
40004 => '排序方式与查询帖子类型要求不匹配',
40005 => '提供了多个唯一查询参数',
],
401 => [
40101 => 'Google reCAPTCHA 验证未通过 请刷新页面/更换设备/网络环境后重试',
],
404 => [
40401 => '帖子查询结果为空',
40402 => '用户查询结果为空',
40403 => '吧帖量统计查询结果为空',
40406 => '指定查询的贴吧不存在',
],
500 => [
50001 => '数据库中存在多个贴吧表存储了该 ID 的帖子',
],
];

public static function abortAPI(int $errorCode): never
{
$statusCodeAndErrorInfos = [
// httpStatusCode => [ errorCode => errorInfo ]
400 => [
// 40000 => App\Exceptions\Handler::convertValidationExceptionToResponse()
40001 => '帖子查询类型必须为索引或搜索查询',
40002 => '搜索查询必须指定查询贴吧',
40003 => '部分查询参数与查询帖子类型要求不匹配',
40004 => '排序方式与查询帖子类型要求不匹配',
40005 => '提供了多个唯一查询参数',
],
401 => [
40101 => 'Google reCAPTCHA 验证未通过 请刷新页面/更换设备/网络环境后重试',
],
404 => [
40401 => '帖子查询结果为空',
40402 => '用户查询结果为空',
40403 => '吧帖量统计查询结果为空',
40406 => '指定查询的贴吧不存在',
],
500 => [
50001 => '数据库中存在多个贴吧表存储了该 ID 的帖子',
],
];

$statusCode = 0;

Check warning on line 83 in be/app/Helper.php

View workflow job for this annotation

GitHub Actions / runs-on (ubuntu-latest) / phpunit-infection

Escaped Mutant for Mutator "DecrementInteger": --- Original +++ New @@ @@ ]; public static function abortAPI(int $errorCode) : never { - $statusCode = 0; + $statusCode = -1; $errorInfo = null; foreach (self::ERROR_STATUS_CODE_INFO as $infoStatusCode => $infoErrorInfo) { if (\array_key_exists($errorCode, $infoErrorInfo)) {

Check warning on line 83 in be/app/Helper.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpunit-infection

Escaped Mutant for Mutator "DecrementInteger": --- Original +++ New @@ @@ ]; public static function abortAPI(int $errorCode) : never { - $statusCode = 0; + $statusCode = -1; $errorInfo = null; foreach (self::ERROR_STATUS_CODE_INFO as $infoStatusCode => $infoErrorInfo) { if (\array_key_exists($errorCode, $infoErrorInfo)) {

Check warning on line 83 in be/app/Helper.php

View workflow job for this annotation

GitHub Actions / runs-on (macos-latest) / phpunit-infection

Escaped Mutant for Mutator "DecrementInteger": --- Original +++ New @@ @@ ]; public static function abortAPI(int $errorCode) : never { - $statusCode = 0; + $statusCode = -1; $errorInfo = null; foreach (self::ERROR_STATUS_CODE_INFO as $infoStatusCode => $infoErrorInfo) { if (\array_key_exists($errorCode, $infoErrorInfo)) {
$errorInfo = null;
foreach ($statusCodeAndErrorInfos as $infoStatusCode => $infoErrorInfo) {
foreach (self::ERROR_STATUS_CODE_INFO as $infoStatusCode => $infoErrorInfo) {
if (\array_key_exists($errorCode, $infoErrorInfo)) {
$statusCode = $infoStatusCode;
$errorInfo = $infoErrorInfo[$errorCode];
Expand Down
2 changes: 1 addition & 1 deletion be/app/Http/PostsQuery/CursorCodec.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ public function decodeCursor(string $encodedCursors, string $orderByField): Coll
// filter out cursors with all fields value being null, their encoded cursor is ',,'
->reject(static fn(Collection $cursors) =>
$cursors->every(static fn(int|string|null $cursor) => $cursor === null))
->map(static fn(Collection $cursors) => new Cursor($cursors->toArray()));
->map(static fn(Collection $cursors) => new Cursor($cursors->all()));
}
}
81 changes: 81 additions & 0 deletions be/tests/Feature/App/HelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Tests\Feature\App;

use App\Helper;
use Illuminate\Http\Exceptions\HttpResponseException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\String\UnicodeString;
use Tests\TestCase;

#[CoversClass(Helper::class)]
class HelperTest extends TestCase
{
public static function assertAbort(int $statusCode, int $errorCode, string $errorInfo, callable $callback): void
{
try {
$callback();
} catch (HttpResponseException $e) {
$response = $e->getResponse();
self::assertEquals($statusCode, $response->getStatusCode());
$responseContent = \Safe\json_decode($response->getContent());
self::assertEquals($errorCode, $responseContent->errorCode);
self::assertEquals($errorInfo, $responseContent->errorInfo);
}
}

#[DataProvider('provideAbortAPI')]
public function testAbortAPI(int $statusCode, int $errorCode, string $errorInfo): void
{
self::assertAbort($statusCode, $errorCode, $errorInfo, static fn() => Helper::abortAPI($errorCode));
}

#[DataProvider('provideAbortAPI')]
public function testAbortAPIIf(int $statusCode, int $errorCode, string $errorInfo): void
{
self::assertAbort($statusCode, $errorCode, $errorInfo, static fn() => Helper::abortAPIIf($errorCode, true));
}

#[DataProvider('provideAbortAPI')]
public function testAbortAPIIfNot(int $statusCode, int $errorCode, string $errorInfo): void
{
self::assertAbort($statusCode, $errorCode, $errorInfo, static fn() => Helper::abortAPIIfNot($errorCode, false));
}

public static function provideAbortAPI(): array
{
return collect(Helper::ERROR_STATUS_CODE_INFO)
->flatMap(static fn(array $codeWithInfo, int $statusCode) => array_map(
static fn(int $errorCode, string $errorInfo) => [$statusCode, $errorCode, $errorInfo],
array_keys($codeWithInfo),
$codeWithInfo,
))
->all();
}

#[DataProvider('provideAbortAPIWithNonExistsCode')]
public function testAbortAPIWithNonExistsCode(int $errorCode): void
{
$this->expectExceptionObject(new \InvalidArgumentException('Given error code doesn\'t existed'));
Helper::abortAPI($errorCode);
}

public static function provideAbortAPIWithNonExistsCode(): array
{
return [[collect(Helper::ERROR_STATUS_CODE_INFO)->max(static fn(array $i) => max(array_keys($i))) + 1]];
}

#[DataProvider('provideXmlResponse')]
public function testXmlResponse(string|\Stringable $xml): void
{
$response = Helper::xmlResponse($xml);
self::assertEquals('<?xml version="1.0" encoding="UTF-8"?>' . "\n$xml", $response->getContent());
self::assertEquals('text/xml', $response->headers->get('Content-Type'));
}

public static function provideXmlResponse(): array
{
return [['<test />'], [new UnicodeString('<test />')]];
}
}
4 changes: 1 addition & 3 deletions be/tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

// @phpcs:ignore PSR2.Classes.ClassDeclaration.OpenBraceNewLine -- https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/566
abstract class TestCase extends BaseTestCase {}
abstract class TestCase extends \Illuminate\Foundation\Testing\TestCase {}

0 comments on commit dc4d69b

Please sign in to comment.