diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 70336c4b..8529d908 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -17,21 +17,4 @@ class Handler extends ExceptionHandler ValidationException::class, PrettyPageException::class, ]; - - public function render($request, Exception $e) - { - if ($e instanceof ValidationException) { - if ($request->expectsJson()) { - return response()->json([ - 'errno' => 1, - 'msg' => $e->validator->errors()->first(), - ]); - } else { - $request->session()->flash('errors', $e->validator->errors()); - return redirect()->back(); - } - } - - return parent::render($request, $e); - } } diff --git a/resources/assets/src/scripts/net.ts b/resources/assets/src/scripts/net.ts index d41e3306..b0e7559e 100644 --- a/resources/assets/src/scripts/net.ts +++ b/resources/assets/src/scripts/net.ts @@ -35,6 +35,19 @@ export async function walkFetch(request: Request): Promise { ? response.json() : response.text() } + + // Process validation errors from Laravel. + if (response.status === 422) { + const { errors }: { + message: string, + errors: { [field: string]: string[] } + } = await response.json() + return { + errno: 1, + msg: Object.keys(errors).map(field => errors[field][0])[0], + } + } + const res = response.clone() throw new HTTPError(await response.text(), res) } catch (error) { diff --git a/resources/assets/tests/scripts/net.test.ts b/resources/assets/tests/scripts/net.test.ts index 4a42e9e4..7df93f0e 100644 --- a/resources/assets/tests/scripts/net.test.ts +++ b/resources/assets/tests/scripts/net.test.ts @@ -122,6 +122,24 @@ test('low level fetch', async () => { expect(await net.walkFetch(request as Request)).toBe('text') }) +test('process Laravel validation errors', async () => { + window.fetch = jest.fn().mockResolvedValue({ + status: 422, + json() { + return Promise.resolve({ + errors: { name: ['required'] }, + }) + }, + }) + + const result: { + errno: number, + msg: string + } = await net.walkFetch({ headers: new Headers() } as Request) + expect(result.errno).toBe(1) + expect(result.msg).toBe('required') +}) + test('inject to Vue instance', () => { expect(typeof Vue.prototype.$http.get).toBe('function') expect(typeof Vue.prototype.$http.post).toBe('function') diff --git a/tests/AdminControllerTest.php b/tests/AdminControllerTest.php index 71d9ae20..ee8f3cd2 100644 --- a/tests/AdminControllerTest.php +++ b/tests/AdminControllerTest.php @@ -38,10 +38,7 @@ class AdminControllerTest extends BrowserKitTestCase { // Check if `color_scheme` is existed or not $this->getJson('/admin/customize?action=color') - ->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'color scheme']), - ]); + ->seeJsonStructure(['errors' => ['color_scheme']]); // Change color $this->get('/admin/customize?action=color&color_scheme=purple') @@ -331,20 +328,14 @@ class AdminControllerTest extends BrowserKitTestCase '/admin/users', ['uid' => $user->uid, 'action' => 'email'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'email']), - ]); + )->seeJsonStructure(['errors' => ['email']]); // Action is `email` but with an invalid email address $this->postJson( '/admin/users', ['uid' => $user->uid, 'action' => 'email', 'email' => 'invalid'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.email', ['attribute' => 'email']), - ]); + )->seeJsonStructure(['errors' => ['email']]); // Using an existed email address $this->postJson( @@ -386,20 +377,14 @@ class AdminControllerTest extends BrowserKitTestCase '/admin/users', ['uid' => $user->uid, 'action' => 'nickname'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'nickname']), - ]); + )->seeJsonStructure(['errors' => ['nickname']]); // Action is `nickname` but with an invalid nickname $this->postJson( '/admin/users', ['uid' => $user->uid, 'action' => 'nickname', 'nickname' => '\\'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'nickname']), - ]); + )->seeJsonStructure(['errors' => ['nickname']]); // Set nickname successfully $this->postJson( @@ -419,30 +404,21 @@ class AdminControllerTest extends BrowserKitTestCase '/admin/users', ['uid' => $user->uid, 'action' => 'password'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'password']), - ]); + )->seeJsonStructure(['errors' => ['password']]); // Set a too short password $this->postJson( '/admin/users', ['uid' => $user->uid, 'action' => 'password', 'password' => '1'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 8]), - ]); + )->seeJsonStructure(['errors' => ['password']]); // Set a too long password $this->postJson( '/admin/users', ['uid' => $user->uid, 'action' => 'password', 'password' => Str::random(17)], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 16]), - ]); + )->seeJsonStructure(['errors' => ['password']]); // Set password successfully $this->postJson( @@ -460,20 +436,14 @@ class AdminControllerTest extends BrowserKitTestCase '/admin/users', ['uid' => $user->uid, 'action' => 'score'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'score']), - ]); + )->seeJsonStructure(['errors' => ['score']]); // Action is `score` but with an not-an-integer value $this->postJson( '/admin/users', ['uid' => $user->uid, 'action' => 'score', 'score' => 'string'], ['Accept' => 'application/json'] - )->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'score']), - ]); + )->seeJsonStructure(['errors' => ['score']]); // Set score successfully $this->postJson( @@ -493,10 +463,7 @@ class AdminControllerTest extends BrowserKitTestCase 'uid' => $user->uid, 'action' => 'permission', 'permission' => -2 - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.in', ['attribute' => 'permission']), - ]); + ])->seeJsonStructure(['errors' => ['permission']]); $user = User::find($user->uid); $this->assertEquals(User::NORMAL, $user->permission); @@ -564,10 +531,7 @@ class AdminControllerTest extends BrowserKitTestCase 'action' => 'texture', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'type']), - ]); + ])->seeJsonStructure(['errors' => ['type']]); // Change texture without `tid` field $this->postJson('/admin/players', [ @@ -576,10 +540,7 @@ class AdminControllerTest extends BrowserKitTestCase 'type' => 'skin', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + ])->seeJsonStructure(['errors' => ['tid']]); // Change texture with a not-integer value $this->postJson('/admin/players', [ @@ -589,10 +550,7 @@ class AdminControllerTest extends BrowserKitTestCase 'tid' => 'string', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + ])->seeJsonStructure(['errors' => ['tid']]); // Invalid texture $this->postJson('/admin/players', [ @@ -666,10 +624,7 @@ class AdminControllerTest extends BrowserKitTestCase 'action' => 'owner', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'uid']), - ]); + ])->seeJsonStructure(['errors' => ['uid']]); // Change owner with a not-integer `uid` value $this->postJson('/admin/players', [ @@ -678,10 +633,7 @@ class AdminControllerTest extends BrowserKitTestCase 'uid' => 'string', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'uid']), - ]); + ])->seeJsonStructure(['errors' => ['uid']]); // Change owner to a not-existed user $this->postJson('/admin/players', [ @@ -713,10 +665,7 @@ class AdminControllerTest extends BrowserKitTestCase 'action' => 'name', ], [ 'Accept' => 'application/json', - ])->seeJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'name']), - ]); + ])->seeJsonStructure(['errors' => ['name']]); // Rename a player successfully $this->postJson('/admin/players', [ diff --git a/tests/AuthControllerTest.php b/tests/AuthControllerTest.php index 404b46ef..e12f9970 100644 --- a/tests/AuthControllerTest.php +++ b/tests/AuthControllerTest.php @@ -45,39 +45,26 @@ class AuthControllerTest extends TestCase $player = factory(Player::class)->create(['uid' => $user->uid]); // Should return a warning if `identification` is empty - $this->postJson('/auth/login') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => trans('validation.attributes.identification')]), - ]); + $this->postJson('/auth/login')->assertJsonValidationErrors('identification'); // Should return a warning if `password` is empty $this->postJson( '/auth/login', ['identification' => $user->email] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'password']), - ]); + )->assertJsonValidationErrors('password'); // Should return a warning if length of `password` is lower than 6 $this->postJson( '/auth/login', [ 'identification' => $user->email, 'password' => '123', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 6]), - ]); + ])->assertJsonValidationErrors('password'); // Should return a warning if length of `password` is greater than 32 $this->postJson( '/auth/login', [ 'identification' => $user->email, 'password' => Str::random(80), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('password'); $this->flushSession(); @@ -105,10 +92,7 @@ class AuthControllerTest extends TestCase '/auth/login', [ 'identification' => $user->email, 'password' => '12345678', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'captcha']), - ]); + ])->assertJsonValidationErrors('captcha'); Cache::flush(); $this->flushSession(); @@ -187,39 +171,26 @@ class AuthControllerTest extends TestCase $this->expectsEvents(Events\UserRegistered::class); // Should return a warning if `email` is empty - $this->postJson('/auth/register') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'email']), - ]); + $this->postJson('/auth/register')->assertJsonValidationErrors('email'); // Should return a warning if `email` is invalid $this->postJson( '/auth/register', ['email' => 'not_an_email'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.email', ['attribute' => 'email']), - ]); + )->assertJsonValidationErrors('email'); // An existed user $existedUser = factory(User::class)->create(); $this->postJson( '/auth/register', ['email' => $existedUser->email] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.unique', ['attribute' => 'email']), - ]); + )->assertJsonValidationErrors('email'); // Should return a warning if `password` is empty $this->postJson( '/auth/register', ['email' => 'a@b.c'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'password']), - ]); + )->assertJsonValidationErrors('password'); // Should return a warning if length of `password` is lower than 8 $this->postJson( @@ -228,10 +199,7 @@ class AuthControllerTest extends TestCase 'email' => 'a@b.c', 'password' => '1', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 8]), - ]); + )->assertJsonValidationErrors('password'); // Should return a warning if length of `password` is greater than 32 $this->postJson( @@ -240,10 +208,7 @@ class AuthControllerTest extends TestCase 'email' => 'a@b.c', 'password' => Str::random(33), ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32]), - ]); + )->assertJsonValidationErrors('password'); // The register_with_player_name option is set to true by default. // Should return a warning if `player_name` is empty @@ -254,10 +219,7 @@ class AuthControllerTest extends TestCase 'password' => '12345678', 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => trans('validation.attributes.player_name')]), - ]); + )->assertJsonValidationErrors('player_name'); // Should return a warning if `player_name` is invalid option(['player_name_rule' => 'official']); @@ -269,10 +231,7 @@ class AuthControllerTest extends TestCase 'player_name' => '角色名', 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.player_name', ['attribute' => trans('validation.attributes.player_name')]), - ]); + )->assertJsonValidationErrors('player_name'); // Should return a warning if `player_name` is too long $this->postJson( @@ -283,13 +242,7 @@ class AuthControllerTest extends TestCase 'player_name' => Str::random(option('player_name_length_max') + 10), 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', [ - 'attribute' => trans('validation.attributes.player_name'), - 'max' => option('player_name_length_max'), - ]), - ]); + )->assertJsonValidationErrors('player_name'); // Existed player $player = factory(Player::class)->create(); @@ -317,10 +270,7 @@ class AuthControllerTest extends TestCase 'password' => '12345678', 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'nickname']), - ]); + )->assertJsonValidationErrors('nickname'); // Should return a warning if `nickname` is invalid $this->postJson( @@ -331,10 +281,7 @@ class AuthControllerTest extends TestCase 'nickname' => '\\', 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'nickname']), - ]); + )->assertJsonValidationErrors('nickname'); // Should return a warning if `nickname` is too long $this->postJson( @@ -345,10 +292,7 @@ class AuthControllerTest extends TestCase 'nickname' => Str::random(256), 'captcha' => 'a', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'nickname', 'max' => 255]), - ]); + )->assertJsonValidationErrors('nickname'); // Should return a warning if `captcha` is empty $this->postJson( @@ -358,10 +302,7 @@ class AuthControllerTest extends TestCase 'password' => '12345678', 'nickname' => 'nickname', ] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'captcha']), - ]); + )->assertJsonValidationErrors('captcha'); // Should be forbidden if registering is closed Option::set('user_can_register', false); @@ -533,29 +474,19 @@ class AuthControllerTest extends TestCase $url = URL::temporarySignedRoute('auth.reset', now()->addHour(), ['uid' => $user->uid]); // Should return a warning if `password` is empty - $this->postJson($url) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'password']), - ]); + $this->postJson($url)->assertJsonValidationErrors('password'); // Should return a warning if `password` is too short $this->postJson( $url, [ 'password' => '123', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 8]), - ]); + ])->assertJsonValidationErrors('password'); // Should return a warning if `password` is too long $this->postJson( $url, [ 'password' => Str::random(33), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('password'); // Success $this->postJson( diff --git a/tests/ClosetControllerTest.php b/tests/ClosetControllerTest.php index e89fadfd..1ad634a0 100644 --- a/tests/ClosetControllerTest.php +++ b/tests/ClosetControllerTest.php @@ -87,38 +87,25 @@ class ClosetControllerTest extends TestCase option(['score_per_closet_item' => 10]); // Missing `tid` field - $this->postJson('/user/closet/add') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + $this->postJson('/user/closet/add')->assertJsonValidationErrors('tid'); // `tid` is not a integer $this->postJson( '/user/closet/add', ['tid' => 'string'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + )->assertJsonValidationErrors('tid'); // Missing `name` field $this->postJson( '/user/closet/add', ['tid' => 0] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'name']), - ]); + )->assertJsonValidationErrors('name'); // `name` field has special characters $this->postJson( '/user/closet/add', ['tid' => 0, 'name' => '\\'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'name']), - ]); + )->assertJsonValidationErrors('name'); // The user doesn't have enough score to add a texture $this->user->setScore(0); @@ -172,38 +159,25 @@ class ClosetControllerTest extends TestCase $name = 'new'; // Missing `tid` field - $this->postJson('/user/closet/rename') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + $this->postJson('/user/closet/rename')->assertJsonValidationErrors('tid'); // `tid` is not a integer $this->postJson( '/user/closet/rename', ['tid' => 'string'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + )->assertJsonValidationErrors('tid'); // Missing `new_name` field $this->postJson( '/user/closet/rename', ['tid' => 0] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'new name']), - ]); + )->assertJsonValidationErrors('new_name'); // `new_name` field has special characters $this->postJson( '/user/closet/rename', ['tid' => 0, 'new_name' => '\\'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'new name']), - ]); + )->assertJsonValidationErrors('new_name'); // Rename a not-existed texture $this->postJson( @@ -233,20 +207,13 @@ class ClosetControllerTest extends TestCase $likes = $texture->likes; // Missing `tid` field - $this->postJson('/user/closet/remove') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + $this->postJson('/user/closet/remove')->assertJsonValidationErrors('tid'); // `tid` is not a integer $this->postJson( '/user/closet/remove', ['tid' => 'string'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + )->assertJsonValidationErrors('tid'); // Rename a not-existed texture $this->postJson( diff --git a/tests/PlayerControllerTest.php b/tests/PlayerControllerTest.php index 95fb649e..a1299045 100644 --- a/tests/PlayerControllerTest.php +++ b/tests/PlayerControllerTest.php @@ -41,21 +41,14 @@ class PlayerControllerTest extends TestCase public function testAdd() { // Without player name - $this->postJson('/user/player/add') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => trans('validation.attributes.player_name')]), - ]); + $this->postJson('/user/player/add')->assertJsonValidationErrors('player_name'); // Only A-Za-z0-9_ are allowed option(['player_name_rule' => 'official']); $this->postJson( '/user/player/add', ['player_name' => '角色名'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.player_name', ['attribute' => trans('validation.attributes.player_name')]), - ]); + )->assertJsonValidationErrors('player_name'); // Custom player name rule (regexp) option(['player_name_rule' => 'custom']); @@ -63,10 +56,7 @@ class PlayerControllerTest extends TestCase $this->postJson( '/user/player/add', ['player_name' => 'yjsnpi'] - )->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.player_name', ['attribute' => trans('validation.attributes.player_name')]), - ]); + )->assertJsonValidationErrors('player_name'); // Lack of score option(['player_name_rule' => 'official']); @@ -181,31 +171,21 @@ class PlayerControllerTest extends TestCase ->postJson('/user/player/rename', [ 'pid' => $player->pid, ]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => trans('validation.attributes.player_name')]), - ]); + ->assertJsonValidationErrors('new_player_name'); // Only A-Za-z0-9_ are allowed option(['player_name_rule' => 'official']); $this->postJson('/user/player/rename', [ 'pid' => $player->pid, 'new_player_name' => '角色名', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.player_name', ['attribute' => trans('validation.attributes.player_name')]), - ]); + ])->assertJsonValidationErrors('new_player_name'); // Other invalid characters option(['player_name_rule' => 'cjk']); $this->postJson('/user/player/rename', [ 'pid' => $player->pid, 'new_player_name' => '\\', - ]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.player_name', ['attribute' => trans('validation.attributes.player_name')]), - ]); + ])->assertJsonValidationErrors('new_player_name'); // Use a duplicated player name $name = factory(Player::class)->create()->name; @@ -318,11 +298,9 @@ class PlayerControllerTest extends TestCase option(['single_player' => true]); $user = factory(User::class)->create(); - $this->actingAs($user)->postJson('/user/player/bind') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'player']), - ]); + $this->actingAs($user) + ->postJson('/user/player/bind') + ->assertJsonValidationErrors('player'); $this->postJson('/user/player/bind', ['player' => 'abc']) ->assertJson([ diff --git a/tests/ReportControllerTest.php b/tests/ReportControllerTest.php index 2d9164cd..9c92c8ec 100644 --- a/tests/ReportControllerTest.php +++ b/tests/ReportControllerTest.php @@ -19,24 +19,15 @@ class ReportControllerTest extends TestCase // Without `tid` field $this->actingAs($user) ->postJson('/skinlib/report') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']) - ]); + ->assertJsonValidationErrors('tid'); // Invalid texture $this->postJson('/skinlib/report', ['tid' => $texture->tid - 1]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.exists', ['attribute' => 'tid']) - ]); + ->assertJsonValidationErrors('tid'); // Without `reason` field $this->postJson('/skinlib/report', ['tid' => $texture->tid]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'reason']) - ]); + ->assertJsonValidationErrors('reason'); // Lack of score $user->score = 0; @@ -139,31 +130,19 @@ class ReportControllerTest extends TestCase // Without `id` field $this->actingAs($reporter) ->postJson('/admin/reports') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'id']) - ]); + ->assertJsonValidationErrors('id'); // Not existed $this->postJson('/admin/reports', ['id' => $report->id - 1]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.exists', ['attribute' => 'id']) - ]); + ->assertJsonValidationErrors('id'); // Without `action` field $this->postJson('/admin/reports', ['id' => $report->id]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'action']) - ]); + ->assertJsonValidationErrors('action'); // Invalid action $this->postJson('/admin/reports', ['id' => $report->id, 'action' => 'a']) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.in', ['attribute' => 'action']) - ]); + ->assertJsonValidationErrors('action'); // Only process pending report $this->postJson('/admin/reports', ['id' => $report->id, 'action' => 'reject']) diff --git a/tests/SkinlibControllerTest.php b/tests/SkinlibControllerTest.php index bdeca959..280997b3 100644 --- a/tests/SkinlibControllerTest.php +++ b/tests/SkinlibControllerTest.php @@ -384,35 +384,23 @@ class SkinlibControllerTest extends TestCase ]); // Without `name` field - $this->postJson('/skinlib/upload')->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'name']), - ]); + $this->postJson('/skinlib/upload')->assertJsonValidationErrors('name'); // With some special chars $this->postJson('/skinlib/upload', ['name' => '\\']) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'name']), - ]); + ->assertJsonValidationErrors('name'); // Specified regular expression for texture name option(['texture_name_regexp' => '/\\d+/']); $this->postJson('/skinlib/upload', [ 'name' => 'abc', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.regex', ['attribute' => 'name']), - ]); + ])->assertJsonValidationErrors('name'); option(['texture_name_regexp' => null]); // Without file $this->postJson('/skinlib/upload', [ 'name' => 'texture', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'file']), - ]); + ])->assertJsonValidationErrors('file'); // Too large file option(['max_upload_file_size' => 2]); @@ -420,20 +408,14 @@ class SkinlibControllerTest extends TestCase $this->postJson('/skinlib/upload', [ 'name' => 'texture', 'file' => $upload, - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.file', ['attribute' => 'file', 'max' => '2']), - ]); + ])->assertJsonValidationErrors('file'); option(['max_upload_file_size' => 1024]); // Without `public` field $this->postJson('/skinlib/upload', [ 'name' => 'texture', 'file' => 'content', // Though it is not a file, it is OK - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'public']), - ]); + ])->assertJsonValidationErrors('public'); // Not a PNG image $this->postJson( @@ -843,38 +825,26 @@ class SkinlibControllerTest extends TestCase // Without `tid` field $this->actingAs($uploader) ->postJson('/skinlib/rename') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + ->assertJsonValidationErrors('tid'); // `tid` is not a integer $this->postJson('/skinlib/rename', [ 'tid' => 'str', ]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + ->assertJsonValidationErrors('tid'); // Without `new_name` field $this->postJson('/skinlib/rename', [ 'tid' => $texture->tid, ]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'new name']), - ]); + ->assertJsonValidationErrors('new_name'); // `new_name` has special chars $this->postJson('/skinlib/rename', [ 'tid' => $texture->tid, 'new_name' => '\\', ]) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'new name']), - ]); + ->assertJsonValidationErrors('new_name'); // Non-existed texture $this->postJson('/skinlib/rename', [ diff --git a/tests/UserControllerTest.php b/tests/UserControllerTest.php index bb4876c2..fdbe098e 100644 --- a/tests/UserControllerTest.php +++ b/tests/UserControllerTest.php @@ -217,28 +217,19 @@ class UserControllerTest extends TestCase // Change nickname without `new_nickname` field $this->postJson('/user/profile', ['action' => 'nickname']) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'new nickname']), - ]); + ->assertJsonValidationErrors('new_nickname'); // Invalid nickname $this->postJson('/user/profile', [ 'action' => 'nickname', 'new_nickname' => '\\', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.no_special_chars', ['attribute' => 'new nickname']), - ]); + ])->assertJsonValidationErrors('new_nickname'); // Too long nickname $this->postJson('/user/profile', [ 'action' => 'nickname', 'new_nickname' => Str::random(256), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'new nickname', 'max' => 255]), - ]); + ])->assertJsonValidationErrors('new_nickname'); // Single player option(['single_player' => true]); @@ -260,50 +251,35 @@ class UserControllerTest extends TestCase // Change password without `current_password` field $this->postJson('/user/profile', ['action' => 'password']) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'current password']), - ]); + ->assertJsonValidationErrors('current_password'); // Too short current password $this->postJson('/user/profile', [ 'action' => 'password', 'current_password' => '1', 'new_password' => '12345678', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'current password', 'min' => 6]), - ]); + ])->assertJsonValidationErrors('current_password'); // Too long current password $this->postJson('/user/profile', [ 'action' => 'password', 'current_password' => Str::random(33), 'new_password' => '12345678', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'current password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('current_password'); // Too short new password $this->postJson('/user/profile', [ 'action' => 'password', 'current_password' => '12345678', 'new_password' => '1', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'new password', 'min' => 8]), - ]); + ])->assertJsonValidationErrors('new_password'); // Too long new password $this->postJson('/user/profile', [ 'action' => 'password', 'current_password' => '12345678', 'new_password' => Str::random(33), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'new password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('new_password'); // Wrong old password $this->postJson('/user/profile', [ @@ -336,39 +312,27 @@ class UserControllerTest extends TestCase '/user/profile', ['action' => 'email'] ) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'new email']), - ]); + ->assertJsonValidationErrors('new_email'); // Invalid email $this->postJson('/user/profile', [ 'action' => 'email', 'new_email' => 'not_an_email', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.email', ['attribute' => 'new email']), - ]); + ])->assertJsonValidationErrors('new_email'); // Too short current password $this->postJson('/user/profile', [ 'action' => 'email', 'new_email' => 'a@b.c', 'password' => '1', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 6]), - ]); + ])->assertJsonValidationErrors('password'); // Too long current password $this->postJson('/user/profile', [ 'action' => 'email', 'new_email' => 'a@b.c', 'password' => Str::random(33), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('password'); // Use a duplicated email $this->postJson('/user/profile', [ @@ -413,28 +377,19 @@ class UserControllerTest extends TestCase '/user/profile', ['action' => 'delete'] ) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'password']), - ]); + ->assertJsonValidationErrors('password'); // Too short current password $this->postJson('/user/profile', [ 'action' => 'delete', 'password' => '1', - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.min.string', ['attribute' => 'password', 'min' => 6]), - ]); + ])->assertJsonValidationErrors('password'); // Too long current password $this->postJson('/user/profile', [ 'action' => 'delete', 'password' => Str::random(33), - ])->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32]), - ]); + ])->assertJsonValidationErrors('password'); // Wrong password $this->postJson('/user/profile', [ @@ -475,18 +430,12 @@ class UserControllerTest extends TestCase // Without `tid` field $this->actingAs($user) ->postJson('/user/profile/avatar') - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.required', ['attribute' => 'tid']), - ]); + ->assertJsonValidationErrors('tid'); // TID is not a integer $this->actingAs($user) ->postJson('/user/profile/avatar', ['tid' => 'string']) - ->assertJson([ - 'errno' => 1, - 'msg' => trans('validation.integer', ['attribute' => 'tid']), - ]); + ->assertJsonValidationErrors('tid'); // Texture cannot be found $this->actingAs($user)