From 7ae9a05f0cfb3eceb4ce62bc16f5ea0ccd387b74 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Wed, 3 Jun 2020 14:47:44 +0800 Subject: [PATCH] extract "single-player" function as plugin --- app/Http/Controllers/PlayerController.php | 53 ---------- .../PlayersManagementController.php | 4 +- app/Http/Controllers/UserController.php | 4 - app/Http/Middleware/RequireBindPlayer.php | 40 -------- .../SinglePlayer/UpdateOwnerNickName.php | 21 ---- app/Providers/EventServiceProvider.php | 3 - resources/assets/src/scripts/route.tsx | 5 - resources/assets/src/scripts/urls.ts | 3 +- .../assets/src/views/user/BindPlayers.tsx | 98 ------------------- .../tests/views/user/BindPlayers.test.tsx | 82 ---------------- resources/lang/en/front-end.yml | 2 - resources/lang/en/user.yml | 7 -- resources/views/user/bind.twig | 10 -- routes/web.php | 4 +- .../ControllersTest/PlayerControllerTest.php | 76 -------------- .../PlayersManagementControllerTest.php | 14 +-- .../ControllersTest/UserControllerTest.php | 7 -- .../MiddlewareTest/RequireBindPlayerTest.php | 30 ------ 18 files changed, 6 insertions(+), 457 deletions(-) delete mode 100644 app/Http/Middleware/RequireBindPlayer.php delete mode 100644 app/Listeners/SinglePlayer/UpdateOwnerNickName.php delete mode 100644 resources/assets/src/views/user/BindPlayers.tsx delete mode 100644 resources/assets/tests/views/user/BindPlayers.test.tsx delete mode 100644 resources/views/user/bind.twig delete mode 100644 tests/HttpTest/MiddlewareTest/RequireBindPlayerTest.php diff --git a/app/Http/Controllers/PlayerController.php b/app/Http/Controllers/PlayerController.php index 9957fb3c..f35dd2cd 100644 --- a/app/Http/Controllers/PlayerController.php +++ b/app/Http/Controllers/PlayerController.php @@ -6,7 +6,6 @@ use App\Events\PlayerWasAdded; use App\Events\PlayerWasDeleted; use App\Events\PlayerWillBeAdded; use App\Events\PlayerWillBeDeleted; -use App\Http\Middleware\CheckPlayerOwner; use App\Models\Player; use App\Models\Texture; use App\Models\User; @@ -77,10 +76,6 @@ class PlayerController extends Controller /** @var User */ $user = Auth::user(); - if (option('single_player', false)) { - return json(trans('user.player.add.single'), 1); - } - $name = $request->validate([ 'name' => [ 'required', @@ -138,10 +133,6 @@ class PlayerController extends Controller return json($can->getReason(), 1); } - if (option('single_player', false)) { - return json(trans('user.player.delete.single'), 1); - } - $dispatcher->dispatch('player.deleting', [$player, $user]); event(new PlayerWillBeDeleted($player)); @@ -186,13 +177,6 @@ class PlayerController extends Controller $player->name = $name; $player->save(); - if (option('single_player', false)) { - /** @var User */ - $user = auth()->user(); - $user->nickname = $name; - $user->save(); - } - $dispatcher->dispatch('player.renamed', [$player, $old]); return json( @@ -262,41 +246,4 @@ class PlayerController extends Controller return json(trans('user.player.clear.success', ['name' => $player->name]), 0, $player->toArray()); } - - public function bind(Request $request, Dispatcher $dispatcher) - { - $name = $request->validate([ - 'player' => [ - 'required', - new Rules\PlayerName(), - 'min:'.option('player_name_length_min'), - 'max:'.option('player_name_length_max'), - ], - ])['player']; - /** @var User */ - $user = Auth::user(); - - $player = Player::where('name', $name)->first(); - if (empty($player)) { - $dispatcher->dispatch('player.adding', [$name, $user]); - event(new PlayerWillBeAdded($name)); - - $player = new Player(); - $player->uid = $user->uid; - $player->name = $name; - $player->tid_skin = 0; - $player->save(); - - $dispatcher->dispatch('player.added', [$player, $user]); - event(new PlayerWasAdded($player)); - } elseif ($player->uid != $user->uid) { - return json(trans('user.player.rename.repeated'), 1); - } - - $user->players()->where('name', '<>', $name)->delete(); - $user->nickname = $name; - $user->save(); - - return json(trans('user.player.bind.success'), 0); - } } diff --git a/app/Http/Controllers/PlayersManagementController.php b/app/Http/Controllers/PlayersManagementController.php index d3928df5..aa4faf09 100644 --- a/app/Http/Controllers/PlayersManagementController.php +++ b/app/Http/Controllers/PlayersManagementController.php @@ -56,13 +56,13 @@ class PlayersManagementController extends Controller ], ])['player_name']; - $dispatcher->dispatch('player.name.updating', [$player, $name]); + $dispatcher->dispatch('player.renaming', [$player, $name]); $oldName = $player->name; $player->name = $name; $player->save(); - $dispatcher->dispatch('player.name.updated', [$player, $oldName]); + $dispatcher->dispatch('player.renamed', [$player, $oldName]); return json(trans('admin.players.name.success', ['player' => $player->name]), 0); } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 0c24bcfa..794f20a6 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -217,10 +217,6 @@ class UserController extends Controller switch ($action) { case 'nickname': - if (option('single_player', false)) { - return json(trans('user.profile.nickname.single'), 1); - } - $request->validate(['new_nickname' => 'required']); $nickname = $request->input('new_nickname'); diff --git a/app/Http/Middleware/RequireBindPlayer.php b/app/Http/Middleware/RequireBindPlayer.php deleted file mode 100644 index ced456a1..00000000 --- a/app/Http/Middleware/RequireBindPlayer.php +++ /dev/null @@ -1,40 +0,0 @@ -is('user/player/bind')) { - return redirect('/user'); - } else { - return $next($request); - } - } - - // This allows us to fetch players list. - if ($request->is('user/player/list')) { - return $next($request); - } - - $count = auth()->user()->players()->count(); - - if ($request->is('user/player/bind')) { - if ($count == 1) { - return redirect('/user'); - } else { - return $next($request); - } - } - - if ($count == 1) { - return $next($request); - } else { - return redirect('user/player/bind'); - } - } -} diff --git a/app/Listeners/SinglePlayer/UpdateOwnerNickName.php b/app/Listeners/SinglePlayer/UpdateOwnerNickName.php deleted file mode 100644 index 6e8e08bb..00000000 --- a/app/Listeners/SinglePlayer/UpdateOwnerNickName.php +++ /dev/null @@ -1,21 +0,0 @@ -user; - - if (option('single_player', false) && $owner) { - $owner->nickname = $player->name; - $owner->save(); - } - } -} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index c15c18a9..7de9a8e6 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -33,9 +33,6 @@ class EventServiceProvider extends ServiceProvider 'App\Events\RenderingHeader' => [ Listeners\SerializeGlobals::class, ], - 'player.name.updated' => [ - Listeners\SinglePlayer\UpdateOwnerNickName::class, - ], 'auth.registration.completed' => [ Listeners\SendEmailVerification::class, ], diff --git a/resources/assets/src/scripts/route.tsx b/resources/assets/src/scripts/route.tsx index 395f2953..19d3d958 100644 --- a/resources/assets/src/scripts/route.tsx +++ b/resources/assets/src/scripts/route.tsx @@ -29,11 +29,6 @@ export default [ ), }, - { - path: 'user/player/bind', - react: () => import('../views/user/BindPlayers'), - el: 'form', - }, { path: 'user/profile', module: [() => import('../views/user/profile/index')], diff --git a/resources/assets/src/scripts/urls.ts b/resources/assets/src/scripts/urls.ts index 20963a41..1efa708d 100644 --- a/resources/assets/src/scripts/urls.ts +++ b/resources/assets/src/scripts/urls.ts @@ -37,8 +37,8 @@ export default { user: { home: () => '/user' as const, closet: { - add: () => '/user/closet' as const, page: () => '/user/closet' as const, + add: () => '/user/closet' as const, ids: () => '/user/closet/ids' as const, list: () => '/user/closet/list' as const, rename: (tid: number) => `/user/closet/${tid}`, @@ -48,7 +48,6 @@ export default { player: { add: () => '/user/player' as const, page: () => '/user/player' as const, - bind: () => '/user/player/bind' as const, list: () => '/user/player/list' as const, delete: (player: number) => `/user/player/${player}`, rename: (player: number) => `/user/player/${player}/name`, diff --git a/resources/assets/src/views/user/BindPlayers.tsx b/resources/assets/src/views/user/BindPlayers.tsx deleted file mode 100644 index e73d46aa..00000000 --- a/resources/assets/src/views/user/BindPlayers.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { hot } from 'react-hot-loader/root' -import { t } from '@/scripts/i18n' -import * as fetch from '@/scripts/net' -import { showModal } from '@/scripts/notify' -import { Player } from '@/scripts/types' -import Loading from '@/components/Loading' - -const BindPlayers: React.FC = () => { - const [players, setPlayers] = useState([]) - const [selected, setSelected] = useState('') - const [isLoading, setIsLoading] = useState(false) - const [isPending, setIsPending] = useState(false) - - useEffect(() => { - const getPlayers = async () => { - setIsLoading(true) - const response = await fetch.get>( - '/user/player/list', - ) - const players = response.data.map((player) => player.name) - setPlayers(players) - setSelected(players[0]) - setIsLoading(false) - } - getPlayers() - }, []) - - const handleSubmit = async (event: React.FormEvent) => { - event.preventDefault() - setIsPending(true) - - const { code, message } = await fetch.post( - '/user/player/bind', - { player: selected }, - ) - if (code === 0) { - await showModal({ mode: 'alert', text: message }) - window.location.href = `${blessing.base_url}/user` - } else { - showModal({ mode: 'alert', text: message }) - } - - setIsPending(false) - } - - return isLoading ? ( - - ) : ( -
- {players.length > 0 ? ( - <> -

{t('user.bindExistedPlayer')}

-
- {players.map((player) => ( - - ))} -
- - ) : ( - <> -

{t('user.bindNewPlayer')}

- setSelected(e.target.value)} - /> - - )} - -
- ) -} - -export default hot(BindPlayers) diff --git a/resources/assets/tests/views/user/BindPlayers.test.tsx b/resources/assets/tests/views/user/BindPlayers.test.tsx deleted file mode 100644 index 6897a06c..00000000 --- a/resources/assets/tests/views/user/BindPlayers.test.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import { render, fireEvent, waitFor } from '@testing-library/react' -import { t } from '@/scripts/i18n' -import * as fetch from '@/scripts/net' -import BindPlayers from '@/views/user/BindPlayers' - -jest.mock('@/scripts/net') - -test('loading indicator', () => { - fetch.get.mockResolvedValue({ data: [] }) - const { queryByTitle } = render() - expect(queryByTitle('Loading...')).toBeInTheDocument() -}) - -describe('submit', () => { - it('have existed players', async () => { - fetch.get.mockResolvedValue({ - data: [{ name: 'kumiko' }, { name: 'reina' }], - }) - fetch.post.mockResolvedValue({ code: 0, message: 'success' }) - - const { getByText, getByLabelText, queryByText } = render() - await waitFor(() => expect(fetch.get).toBeCalledTimes(1)) - - fireEvent.click(getByLabelText('reina')) - fireEvent.click(getByText(t('general.submit'))) - await waitFor(() => - expect(fetch.post).toBeCalledWith('/user/player/bind', { - player: 'reina', - }), - ) - expect(queryByText('success')).toBeInTheDocument() - - fireEvent.click(getByText(t('general.confirm'))) - }) - - it('no existed players', async () => { - fetch.get.mockResolvedValue({ data: [] }) - fetch.post.mockResolvedValue({ code: 0, message: 'success' }) - - const { getByText, getByPlaceholderText, queryByText } = render( - , - ) - await waitFor(() => expect(fetch.get).toBeCalledTimes(1)) - - fireEvent.input(getByPlaceholderText(t('general.player.player-name')), { - target: { value: 'kumiko' }, - }) - fireEvent.click(getByText(t('general.submit'))) - await waitFor(() => - expect(fetch.post).toBeCalledWith('/user/player/bind', { - player: 'kumiko', - }), - ) - expect(queryByText('success')).toBeInTheDocument() - - fireEvent.click(getByText(t('general.confirm'))) - }) - - it('failed', async () => { - fetch.get.mockResolvedValue({ data: [] }) - fetch.post.mockResolvedValue({ code: 1, message: 'failed' }) - - const { getByText, getByPlaceholderText, queryByText } = render( - , - ) - await waitFor(() => expect(fetch.get).toBeCalledTimes(1)) - - fireEvent.input(getByPlaceholderText(t('general.player.player-name')), { - target: { value: 'kumiko' }, - }) - fireEvent.click(getByText(t('general.submit'))) - await waitFor(() => - expect(fetch.post).toBeCalledWith('/user/player/bind', { - player: 'kumiko', - }), - ) - expect(queryByText('failed')).toBeInTheDocument() - - fireEvent.click(getByText(t('general.confirm'))) - }) -}) diff --git a/resources/lang/en/front-end.yml b/resources/lang/en/front-end.yml index 2df502bb..423e0766 100644 --- a/resources/lang/en/front-end.yml +++ b/resources/lang/en/front-end.yml @@ -128,8 +128,6 @@ user: typeToSearch: Type to search useAs: Apply... resetSelected: Clear selected - bindNewPlayer: You're required to create a player to go ahead. This player will be bound with your account. - bindExistedPlayer: You're required to select a player to go ahead. This player will be bound with your account. Other players will be deleted. closet: upload: Upload Texture use-as: diff --git a/resources/lang/en/user.yml b/resources/lang/en/user.yml index def53a0f..ab86dd4a 100644 --- a/resources/lang/en/user.yml +++ b/resources/lang/en/user.yml @@ -87,11 +87,9 @@ player: add: repeated: The player name is already registered. lack-score: You don't have enough score to add a player. - single: You must own exactly ONE player so you can't add more. success: Player :name was added successfully. delete: - single: You must own exactly ONE player so you can't delete it. success: Player :name was deleted successfully. rename: @@ -104,10 +102,6 @@ player: clear: success: The textures of player :name was resetted successfully. - bind: - title: Bind Players - success: Bound successfully! - profile: avatar: title: Change Avatar? @@ -128,7 +122,6 @@ profile: nickname: title: Change Nickname empty: No nickname is set now. - single: You're not allowed to update nickname, because we've bound your player with your account. success: Nickname is successfully updated to :nickname email: diff --git a/resources/views/user/bind.twig b/resources/views/user/bind.twig deleted file mode 100644 index b023e9ca..00000000 --- a/resources/views/user/bind.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% extends 'auth.base' %} - -{% block title %}{{ trans('user.player.bind.title') }}{% endblock %} - -{% block content %} - -
-{% endblock %} diff --git a/routes/web.php b/routes/web.php index 7293f16e..ea2a7d53 100644 --- a/routes/web.php +++ b/routes/web.php @@ -48,7 +48,7 @@ Route::prefix('auth')->name('auth.')->group(function () { Route::prefix('user') ->name('user.') - ->middleware(['authorize', Middleware\RequireBindPlayer::class]) + ->middleware(['authorize']) ->group(function () { Route::get('', 'UserController@index')->name('home'); Route::get('notifications/{id}', 'NotificationsController@read')->name('notification'); @@ -76,8 +76,6 @@ Route::prefix('user') Route::delete('{player}/textures', 'PlayerController@clearTexture')->name('clear'); Route::put('{player}/name', 'PlayerController@rename')->name('rename'); Route::delete('{player}', 'PlayerController@delete')->name('delete'); - Route::view('bind', 'user.bind')->name('bind'); - Route::post('bind', 'PlayerController@bind')->name('bind'); }); Route::prefix('closet')->name('closet.')->group(function () { diff --git a/tests/HttpTest/ControllersTest/PlayerControllerTest.php b/tests/HttpTest/ControllersTest/PlayerControllerTest.php index 95f6d815..d278e54d 100644 --- a/tests/HttpTest/ControllersTest/PlayerControllerTest.php +++ b/tests/HttpTest/ControllersTest/PlayerControllerTest.php @@ -158,14 +158,6 @@ class PlayerControllerTest extends TestCase $score - option('score_per_player'), User::find($user->uid)->score ); - - // Single player - option(['single_player' => true]); - $this->postJson(route('user.player.add'), ['name' => 'abc']) - ->assertJson([ - 'code' => 1, - 'message' => trans('user.player.add.single'), - ]); } public function testDelete() @@ -234,17 +226,6 @@ class PlayerControllerTest extends TestCase $user->score, User::find($user->uid)->score ); - - // Single player - option(['single_player' => true]); - $player = factory(Player::class)->create(['uid' => $user->uid]); - $this->actingAs($user) - ->deleteJson(route('user.player.delete', ['player' => $player])) - ->assertJson([ - 'code' => 1, - 'message' => trans('user.player.delete.single'), - ]); - $this->assertNotNull(Player::find($player->pid)); } public function testRename() @@ -329,14 +310,6 @@ class PlayerControllerTest extends TestCase return true; }); - - // Single player - option(['single_player' => true]); - $this->putJson( - route('user.player.rename', ['player' => $player]), - ['name' => 'abc'] - )->assertJson(['code' => 0]); - $this->assertEquals('abc', $player->user->nickname); } public function testSetTexture() @@ -485,53 +458,4 @@ class PlayerControllerTest extends TestCase return true; }); } - - public function testBind() - { - Event::fake(); - option(['single_player' => true]); - $user = factory(User::class)->create(); - - $this->actingAs($user) - ->postJson('/user/player/bind') - ->assertJsonValidationErrors('player'); - - $this->postJson('/user/player/bind', ['player' => 'abc']) - ->assertJson([ - 'code' => 0, - 'message' => trans('user.player.bind.success'), - ]); - Event::assertDispatched('player.adding', function ($event, $payload) use ($user) { - $this->assertEquals('abc', $payload[0]); - $this->assertEquals($user->uid, $payload[1]->uid); - - return true; - }); - Event::assertDispatched('player.added', function ($event, $payload) use ($user) { - $this->assertEquals('abc', $payload[0]->name); - $this->assertEquals($user->uid, $payload[1]->uid); - - return true; - }); - Event::assertDispatched(Events\PlayerWillBeAdded::class); - Event::assertDispatched(Events\PlayerWasAdded::class); - $player = Player::where('name', 'abc')->first(); - $this->assertNotNull($player); - $this->assertEquals($user->uid, $player->uid); - $this->assertEquals('abc', $player->name); - $user->refresh(); - $this->assertEquals('abc', $user->nickname); - - $player2 = factory(Player::class)->create(); - $player3 = factory(Player::class)->create(['uid' => $user->uid]); - $this->postJson('/user/player/bind', ['player' => $player2->name]) - ->assertJson([ - 'code' => 1, - 'message' => trans('user.player.rename.repeated'), - ]); - - $this->postJson('/user/player/bind', ['player' => $player->name]) - ->assertJson(['code' => 0]); - $this->assertNull(Player::where('name', $player3->name)->first()); - } } diff --git a/tests/HttpTest/ControllersTest/PlayersManagementControllerTest.php b/tests/HttpTest/ControllersTest/PlayersManagementControllerTest.php index db748674..ec4b3d4e 100644 --- a/tests/HttpTest/ControllersTest/PlayersManagementControllerTest.php +++ b/tests/HttpTest/ControllersTest/PlayersManagementControllerTest.php @@ -76,16 +76,6 @@ class PlayersManagementControllerTest extends TestCase ['player_name' => $player->name] )->assertJsonValidationErrors(['player_name']); - // single player - option(['single_player' => true]); - $this->putJson( - route('admin.players.name', ['player' => $player->pid]), - ['player_name' => 'abc'] - )->assertJson(['code' => 0]); - $player->refresh(); - $this->assertEquals('abc', $player->user->nickname); - option(['single_player' => false]); - // rename a player successfully Event::fake(); $this->putJson( @@ -99,7 +89,7 @@ class PlayersManagementControllerTest extends TestCase $player->refresh(); $this->assertEquals('new_name', $player->name); Event::assertDispatched( - 'player.name.updating', + 'player.renaming', function ($eventName, $payload) use ($player) { $this->assertEquals($player->pid, $payload[0]->pid); $this->assertEquals('new_name', $payload[1]); @@ -108,7 +98,7 @@ class PlayersManagementControllerTest extends TestCase } ); Event::assertDispatched( - 'player.name.updated', + 'player.renamed', function ($eventName, $payload) use ($player, $oldName) { $this->assertEquals($player->pid, $payload[0]->pid); $this->assertEquals($oldName, $payload[1]); diff --git a/tests/HttpTest/ControllersTest/UserControllerTest.php b/tests/HttpTest/ControllersTest/UserControllerTest.php index 4e077df5..dee95a3e 100644 --- a/tests/HttpTest/ControllersTest/UserControllerTest.php +++ b/tests/HttpTest/ControllersTest/UserControllerTest.php @@ -267,13 +267,6 @@ class UserControllerTest extends TestCase $this->postJson('/user/profile', ['action' => 'nickname']) ->assertJsonValidationErrors('new_nickname'); - // Single player - option(['single_player' => true]); - factory(\App\Models\Player::class)->create(['uid' => $user->uid]); - $this->postJson('/user/profile', ['action' => 'nickname']) - ->assertJson(['code' => 1, 'message' => trans('user.profile.nickname.single')]); - option(['single_player' => false]); - // Change nickname successfully $this->postJson('/user/profile', [ 'action' => 'nickname', diff --git a/tests/HttpTest/MiddlewareTest/RequireBindPlayerTest.php b/tests/HttpTest/MiddlewareTest/RequireBindPlayerTest.php deleted file mode 100644 index 30e49c87..00000000 --- a/tests/HttpTest/MiddlewareTest/RequireBindPlayerTest.php +++ /dev/null @@ -1,30 +0,0 @@ -create(); - $this->actingAs($user)->get('/user')->assertViewIs('user.index'); - $this->get('/user/player/bind')->assertRedirect('/user'); - - option(['single_player' => true]); - - $this->getJson('/user/player/list')->assertHeader('content-type', 'application/json'); - - $this->get('/user/player/bind')->assertViewIs('user.bind'); - $this->get('/user')->assertRedirect('/user/player/bind'); - - factory(Player::class)->create(['uid' => $user->uid]); - $this->get('/user')->assertViewIs('user.index'); - $this->get('/user/player/bind')->assertRedirect('/user'); - } -}