mirror of
https://github.com/bs-community/blessing-skin-server.git
synced 2025-01-18 13:54:01 +08:00
Support limiting single player
This commit is contained in:
parent
6793ccea30
commit
aec3fe4a87
@ -508,11 +508,17 @@ class AdminController extends Controller
|
||||
|
||||
return json(trans('admin.players.delete.success'), 0);
|
||||
} elseif ($action == 'name') {
|
||||
$this->validate($request, [
|
||||
$name = $this->validate($request, [
|
||||
'name' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max'),
|
||||
]);
|
||||
])['name'];
|
||||
|
||||
$player->rename($request->input('name'));
|
||||
$player->rename($name);
|
||||
|
||||
if (option('single_player', false)) {
|
||||
$owner = $player->user;
|
||||
$owner->nickname = $name;
|
||||
$owner->save();
|
||||
}
|
||||
|
||||
return json(trans('admin.players.name.success', ['player' => $player->name]), 0, ['name' => $player->name]);
|
||||
} else {
|
||||
|
@ -65,6 +65,10 @@ class PlayerController extends Controller
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if (option('single_player', false)) {
|
||||
return json(trans('user.player.add.single'), 1);
|
||||
}
|
||||
|
||||
$this->validate($request, [
|
||||
'player_name' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max'),
|
||||
]);
|
||||
@ -99,6 +103,10 @@ class PlayerController extends Controller
|
||||
{
|
||||
$playerName = $this->player->name;
|
||||
|
||||
if (option('single_player', false)) {
|
||||
return json(trans('user.player.delete.single'), 1);
|
||||
}
|
||||
|
||||
event(new PlayerWillBeDeleted($this->player));
|
||||
|
||||
$this->player->delete();
|
||||
@ -133,6 +141,12 @@ class PlayerController extends Controller
|
||||
|
||||
$this->player->rename($newName);
|
||||
|
||||
if (option('single_player', false)) {
|
||||
$user = auth()->user();
|
||||
$user->nickname = $newName;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
return json(trans('user.player.rename.success', ['old' => $oldName, 'new' => $newName]), 0);
|
||||
}
|
||||
|
||||
@ -169,4 +183,34 @@ class PlayerController extends Controller
|
||||
|
||||
return json(trans('user.player.clear.success', ['name' => $this->player->name]), 0);
|
||||
}
|
||||
|
||||
public function bind(Request $request)
|
||||
{
|
||||
$name = $this->validate($request, [
|
||||
'player' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max'),
|
||||
])['player'];
|
||||
$user = Auth::user();
|
||||
|
||||
event(new CheckPlayerExists($name));
|
||||
$player = Player::where('name', $name)->first();
|
||||
if (! $player) {
|
||||
event(new PlayerWillBeAdded($name));
|
||||
|
||||
$player = new Player;
|
||||
$player->uid = $user->uid;
|
||||
$player->name = $name;
|
||||
$player->tid_skin = 0;
|
||||
$player->save();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,10 @@ class UserController extends Controller
|
||||
|
||||
switch ($action) {
|
||||
case 'nickname':
|
||||
if (option('single_player', false)) {
|
||||
return json(trans('user.profile.nickname.single'), 1);
|
||||
}
|
||||
|
||||
$this->validate($request, [
|
||||
'new_nickname' => 'required|no_special_chars|max:255',
|
||||
]);
|
||||
|
40
app/Http/Middleware/RequireBindPlayer.php
Normal file
40
app/Http/Middleware/RequireBindPlayer.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class RequireBindPlayer
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (! option('single_player', false)) {
|
||||
if ($request->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');
|
||||
}
|
||||
}
|
||||
}
|
@ -60,6 +60,27 @@ class User extends Authenticatable
|
||||
return $this->belongsToMany(Texture::class, 'user_closet')->withPivot('item_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the player name of first player.
|
||||
*/
|
||||
public function getPlayerNameAttribute()
|
||||
{
|
||||
$player = $this->players->first();
|
||||
return $player ? $player->name : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the player name of first player.
|
||||
*/
|
||||
public function setPlayerNameAttribute($value)
|
||||
{
|
||||
$player = $this->players->first();
|
||||
if ($player) {
|
||||
$player->name = $value;
|
||||
$player->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given password is correct.
|
||||
*
|
||||
|
@ -18,6 +18,11 @@ export default [
|
||||
component: () => import('./views/user/Players.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'user/player/bind',
|
||||
component: () => import('./views/user/Bind.vue'),
|
||||
el: 'form',
|
||||
},
|
||||
{
|
||||
path: 'user/profile',
|
||||
component: () => import('./views/user/Profile.vue'),
|
||||
|
84
resources/assets/src/views/user/Bind.vue
Normal file
84
resources/assets/src/views/user/Bind.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<form>
|
||||
<div v-if="players.length">
|
||||
<p v-t="'user.bindExistedPlayer'" />
|
||||
<div class="form-group">
|
||||
<select v-model="selected" class="player-select">
|
||||
<option v-for="name in players" :key="name">{{ name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<p v-t="'user.bindNewPlayer'" />
|
||||
<div class="form-group has-feedback">
|
||||
<input
|
||||
v-model="selected"
|
||||
class="form-control"
|
||||
:placeholder="$t('general.player.player-name')"
|
||||
>
|
||||
<span class="glyphicon glyphicon-user form-control-feedback" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="message" class="callout callout-warning" v-text="message" />
|
||||
|
||||
<button v-if="pending" class="btn btn-primary btn-block btn-flat" disabled>
|
||||
<i class="fa fa-spinner fa-spin" /> {{ $t('general.wait') }}
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-primary btn-block btn-flat"
|
||||
@click.prevent="submit"
|
||||
>
|
||||
{{ $t('general.submit') }}
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { swal } from '../../js/notify'
|
||||
|
||||
export default {
|
||||
name: 'BindPlayer',
|
||||
data() {
|
||||
return {
|
||||
players: [],
|
||||
selected: '',
|
||||
pending: false,
|
||||
message: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fetchPlayers()
|
||||
},
|
||||
methods: {
|
||||
async fetchPlayers() {
|
||||
const players = await this.$http.get('/user/player/list')
|
||||
this.players = players.map(player => player.name)
|
||||
;[this.selected] = this.players
|
||||
},
|
||||
async submit() {
|
||||
this.pending = true
|
||||
const { errno, msg } = await this.$http.post(
|
||||
'/user/player/bind',
|
||||
{ player: this.selected }
|
||||
)
|
||||
this.pending = false
|
||||
if (errno === 0) {
|
||||
await swal({ text: msg, type: 'success' })
|
||||
window.location.href = `${blessing.base_url}/user`
|
||||
} else {
|
||||
this.message = msg
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
@import "../../stylus/auth.styl"
|
||||
|
||||
.player-select
|
||||
width 100%
|
||||
</style>
|
42
resources/assets/tests/views/user/Bind.test.ts
Normal file
42
resources/assets/tests/views/user/Bind.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Bind from '@/views/user/Bind.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
||||
|
||||
test('list existed players', async () => {
|
||||
Vue.prototype.$http.get
|
||||
.mockResolvedValue([{ name: 'a' }, { name: 'b' }])
|
||||
const wrapper = mount(Bind)
|
||||
await wrapper.vm.$nextTick()
|
||||
const options = wrapper.findAll('option')
|
||||
expect(options).toHaveLength(2)
|
||||
})
|
||||
|
||||
test('show input box', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([])
|
||||
const wrapper = mount(Bind)
|
||||
await wrapper.vm.$nextTick()
|
||||
const input = wrapper.find('input')
|
||||
expect(input.exists()).toBeTrue()
|
||||
})
|
||||
|
||||
test('submit', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([])
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: 'fail' })
|
||||
.mockResolvedValueOnce({ errno: 0, msg: 'ok' })
|
||||
swal.mockResolvedValue({})
|
||||
|
||||
const wrapper = mount(Bind)
|
||||
wrapper.find('input').setValue('abc')
|
||||
|
||||
wrapper.find('button').trigger('click')
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.callout').text()).toBe('fail')
|
||||
|
||||
wrapper.find('button').trigger('click')
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(swal).toBeCalledWith({ text: 'ok', type: 'success' })
|
||||
})
|
@ -139,6 +139,8 @@ 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:
|
||||
use-as:
|
||||
button: Apply...
|
||||
@ -328,6 +330,7 @@ general:
|
||||
reset: Reset
|
||||
skinlib: Skin Library
|
||||
loading: Loading
|
||||
wait: Please wait...
|
||||
user:
|
||||
email: Email
|
||||
nickname: Nick Name
|
||||
|
@ -93,9 +93,11 @@ 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:
|
||||
@ -108,6 +110,10 @@ player:
|
||||
clear:
|
||||
success: The textures of player :name was resetted successfully.
|
||||
|
||||
bind:
|
||||
title: Bind Players
|
||||
success: Bound successfully!
|
||||
|
||||
profile:
|
||||
avatar:
|
||||
title: Change Avatar?
|
||||
@ -128,6 +134,7 @@ profile:
|
||||
title: Change Nickname
|
||||
empty: No nickname is set now.
|
||||
rule: Whatever you like expect special characters
|
||||
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:
|
||||
|
@ -139,6 +139,8 @@ user:
|
||||
typeToSearch: 输入即搜索
|
||||
useAs: 使用...
|
||||
resetSelected: 重置已选材质
|
||||
bindNewPlayer: 您现在需要创建一个角色,才能继续使用我们的服务。这个角色将与您的账号绑定。
|
||||
bindExistedPlayer: 您现在需要选择一个角色,才能继续使用我们的服务。这个角色将与您的账号绑定。其它角色将被删除。
|
||||
closet:
|
||||
use-as:
|
||||
button: 使用...
|
||||
@ -322,6 +324,7 @@ general:
|
||||
reset: 重置
|
||||
skinlib: 皮肤库
|
||||
loading: 正在加载
|
||||
wait: 请稍等...
|
||||
user:
|
||||
email: 邮箱
|
||||
nickname: 昵称
|
||||
|
@ -102,9 +102,11 @@ player:
|
||||
add:
|
||||
repeated: 该角色名已被占用
|
||||
lack-score: 添加角色失败,积分不足
|
||||
single: 您必须拥有且只有一个角色,因此您不能添加更多角色。
|
||||
success: 成功添加了角色 :name
|
||||
|
||||
delete:
|
||||
single: 您必须拥有且只有一个角色,因此您不能删除。
|
||||
success: 角色 :name 已被删除
|
||||
|
||||
rename:
|
||||
@ -117,6 +119,10 @@ player:
|
||||
clear:
|
||||
success: 角色 :name 的材质已被成功重置
|
||||
|
||||
bind:
|
||||
title: 绑定角色
|
||||
success: 绑定成功
|
||||
|
||||
profile:
|
||||
avatar:
|
||||
title: 更改头像?
|
||||
@ -137,6 +143,7 @@ profile:
|
||||
title: 更改昵称
|
||||
empty: 当前未设置昵称,
|
||||
rule: 可使用除一些特殊符号外的任意字符
|
||||
single: 您不能更改昵称,因为我们已将角色与您的账号进行了绑定。
|
||||
success: 昵称已成功设置为 :nickname
|
||||
|
||||
email:
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg">@lang('auth.bind.message')</p>
|
||||
|
||||
<form method="post" id="login-form">
|
||||
<form method="post" id="login-form">
|
||||
@csrf
|
||||
<div class="form-group has-feedback">
|
||||
<input name="email" type="email" class="form-control" placeholder="@lang('auth.email')">
|
||||
|
16
resources/views/user/bind.blade.php
Normal file
16
resources/views/user/bind.blade.php
Normal file
@ -0,0 +1,16 @@
|
||||
@extends('auth.master')
|
||||
|
||||
@section('title', trans('user.player.bind.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
<a href="{{ url('/') }}">{{ option_localized('site_name') }}</a>
|
||||
</div>
|
||||
<!-- /.login-logo -->
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg">@lang('user.player.bind.title')</p>
|
||||
<form></form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -41,7 +41,10 @@ Route::group(['prefix' => 'auth'], function () {
|
||||
/*
|
||||
* User Center
|
||||
*/
|
||||
Route::group(['middleware' => ['web', 'auth'], 'prefix' => 'user'], function () {
|
||||
Route::group([
|
||||
'middleware' => ['web', 'auth', \App\Http\Middleware\RequireBindPlayer::class],
|
||||
'prefix' => 'user'
|
||||
], function () {
|
||||
Route::any('', 'UserController@index');
|
||||
Route::get('/score-info', 'UserController@scoreInfo');
|
||||
Route::post('/sign', 'UserController@sign');
|
||||
@ -64,6 +67,8 @@ Route::group(['middleware' => ['web', 'auth'], 'prefix' => 'user'], function ()
|
||||
Route::post('/texture/clear', 'PlayerController@clearTexture');
|
||||
Route::post('/rename', 'PlayerController@rename');
|
||||
Route::post('/delete', 'PlayerController@delete');
|
||||
Route::view('/bind', 'user.bind');
|
||||
Route::post('/bind', 'PlayerController@bind');
|
||||
});
|
||||
|
||||
// Closet
|
||||
|
@ -711,6 +711,16 @@ class AdminControllerTest extends BrowserKitTestCase
|
||||
'name' => 'new_name',
|
||||
]);
|
||||
|
||||
// Single player
|
||||
option(['single_player' => true]);
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'name',
|
||||
'name' => 'abc',
|
||||
])->seeJson(['errno' => 0]);
|
||||
$player->refresh();
|
||||
$this->assertEquals('abc', $player->user->nickname);
|
||||
|
||||
// Delete a player
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
|
@ -295,6 +295,7 @@ class AuthControllerTest extends TestCase
|
||||
'errno' => 2,
|
||||
'msg' => trans('user.player.add.repeated'),
|
||||
]);
|
||||
$this->assertNull(User::where('email', 'a@b.c')->first());
|
||||
|
||||
option(['register_with_player_name' => false]);
|
||||
|
||||
|
@ -4,6 +4,7 @@ namespace Tests;
|
||||
|
||||
use DB;
|
||||
use App\Models\User;
|
||||
use App\Models\Player;
|
||||
use App\Services\Facades\Option;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
@ -196,4 +197,22 @@ class MiddlewareTest extends TestCase
|
||||
->get('/auth/login')
|
||||
->assertRedirect('/user');
|
||||
}
|
||||
|
||||
public function testRequireBindPlayer()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$this->actAs($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');
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Tests;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Player;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class UserTest extends TestCase
|
||||
@ -26,4 +27,20 @@ class UserTest extends TestCase
|
||||
$user->getNickName()
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetPlayerNameAttribute()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$player = factory(Player::class)->create(['uid' => $user->uid]);
|
||||
$this->assertEquals($player->name, $user->player_name);
|
||||
}
|
||||
|
||||
public function testSetPlayerNameAttribute()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$player = factory(Player::class)->create(['uid' => $user->uid]);
|
||||
$user->player_name = 'a';
|
||||
$player->refresh();
|
||||
$this->assertEquals('a', $player->name);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Event;
|
||||
use App\Events;
|
||||
use App\Models\User;
|
||||
use App\Models\Player;
|
||||
@ -108,6 +109,14 @@ class PlayerControllerTest extends TestCase
|
||||
'errno' => 6,
|
||||
'msg' => trans('user.player.add.repeated'),
|
||||
]);
|
||||
|
||||
// Single player
|
||||
option(['single_player' => true]);
|
||||
$this->postJson('/user/player/add', ['player_name' => 'abc'])
|
||||
->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('user.player.add.single'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
@ -143,6 +152,17 @@ 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)
|
||||
->postJson('/user/player/delete', ['pid' => $player->pid])
|
||||
->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('user.player.delete.single'),
|
||||
]);
|
||||
$this->assertNotNull(Player::find($player->pid));
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
@ -210,6 +230,14 @@ class PlayerControllerTest extends TestCase
|
||||
['old' => $player->name, 'new' => 'new_name']
|
||||
),
|
||||
]);
|
||||
|
||||
// Single player
|
||||
option(['single_player' => true]);
|
||||
$this->postJson('/user/player/rename', [
|
||||
'pid' => $player->pid,
|
||||
'new_player_name' => 'abc',
|
||||
])->assertJson(['errno' => 0]);
|
||||
$this->assertEquals('abc', $player->user->nickname);
|
||||
}
|
||||
|
||||
public function testSetTexture()
|
||||
@ -284,4 +312,44 @@ class PlayerControllerTest extends TestCase
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_skin);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_cape);
|
||||
}
|
||||
|
||||
public function testBind()
|
||||
{
|
||||
Event::fake();
|
||||
option(['single_player' => true]);
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
$this->actAs($user)->postJson('/user/player/bind')
|
||||
->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.required', ['attribute' => 'player']),
|
||||
]);
|
||||
|
||||
$this->postJson('/user/player/bind', ['player' => 'abc'])
|
||||
->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.bind.success')
|
||||
]);
|
||||
Event::assertDispatched(Events\CheckPlayerExists::class);
|
||||
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([
|
||||
'errno' => 1,
|
||||
'msg' => trans('user.player.rename.repeated')
|
||||
]);
|
||||
|
||||
$this->postJson('/user/player/bind', ['player' => $player->name])
|
||||
->assertJson(['errno' => 0]);
|
||||
$this->assertNull(Player::where('name', $player3->name)->first());
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +243,13 @@ class UserControllerTest extends TestCase
|
||||
'msg' => trans('validation.max.string', ['attribute' => 'new nickname', 'max' => 255]),
|
||||
]);
|
||||
|
||||
// Single player
|
||||
option(['single_player' => true]);
|
||||
factory(\App\Models\Player::class)->create(['uid' => $user->uid]);
|
||||
$this->postJson('/user/profile', ['action' => 'nickname'])
|
||||
->assertJson(['errno' => 1, 'msg' => trans('user.profile.nickname.single')]);
|
||||
option(['single_player' => false]);
|
||||
|
||||
// Change nickname successfully
|
||||
$this->expectsEvents(Events\UserProfileUpdated::class);
|
||||
$this->postJson('/user/profile', [
|
||||
|
Loading…
Reference in New Issue
Block a user