2017-11-17 07:40:29 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
use App\Models\User;
|
|
|
|
use App\Models\Player;
|
|
|
|
use App\Models\Texture;
|
|
|
|
use Illuminate\Foundation\Testing\WithoutMiddleware;
|
|
|
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
|
|
|
|
|
|
class TextureControllerTest extends TestCase
|
|
|
|
{
|
|
|
|
use DatabaseTransactions;
|
|
|
|
|
|
|
|
public function testJson()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
|
|
|
|
// Player is not existed
|
|
|
|
$this->get('/nope.json')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.unexistent-player'))
|
|
|
|
->assertStatus(404);
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
// Player is banned
|
|
|
|
$player = factory(Player::class)->create(['tid_steve' => $steve->tid]);
|
2018-07-16 10:22:19 +08:00
|
|
|
$player->user->setPermission(User::BANNED);
|
2017-11-17 07:40:29 +08:00
|
|
|
$this->get("/{$player->player_name}.json")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.player-banned'))
|
|
|
|
->assertStatus(403);
|
2017-11-17 07:40:29 +08:00
|
|
|
|
2018-07-16 10:22:19 +08:00
|
|
|
$player->user->setPermission(User::NORMAL);
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
// Default API is CSL API
|
2018-07-13 15:21:13 +08:00
|
|
|
$this->getJson("/{$player->player_name}.json")
|
|
|
|
->assertJson([
|
2017-11-17 07:40:29 +08:00
|
|
|
'username' => $player->player_name,
|
|
|
|
'skins' => [
|
|
|
|
'default' => $steve->hash,
|
|
|
|
'slim' => null
|
|
|
|
],
|
|
|
|
'cape' => null
|
2018-07-13 15:21:13 +08:00
|
|
|
])->assertHeader('Last-Modified');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testJsonWithApi()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
$player = factory(Player::class)->create(['tid_steve' => $steve->tid]);
|
|
|
|
|
|
|
|
// CSL API
|
2018-07-13 15:21:13 +08:00
|
|
|
$this->getJson("/csl/{$player->player_name}.json")
|
|
|
|
->assertJson([
|
2017-11-17 07:40:29 +08:00
|
|
|
'username' => $player->player_name,
|
|
|
|
'skins' => [
|
|
|
|
'default' => $steve->hash,
|
|
|
|
'slim' => null
|
|
|
|
],
|
|
|
|
'cape' => null
|
2018-07-13 15:21:13 +08:00
|
|
|
])->assertHeader('Last-Modified');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
// USM API
|
2018-07-13 15:21:13 +08:00
|
|
|
$this->getJson("/usm/{$player->player_name}.json")
|
|
|
|
->assertJson([
|
2017-11-17 07:40:29 +08:00
|
|
|
'player_name' => $player->player_name,
|
|
|
|
'model_preference' => ['default', 'slim'],
|
|
|
|
'skins' => [
|
|
|
|
'default' => $steve->hash,
|
|
|
|
'slim' => null
|
|
|
|
],
|
|
|
|
'cape' => null
|
2018-07-13 15:21:13 +08:00
|
|
|
])->assertHeader('Last-Modified');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testTexture()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
Storage::disk('textures')->put($steve->hash, '');
|
|
|
|
$this->get('/textures/nope')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee('404');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$this->get('/textures/'.$steve->hash)
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png')
|
|
|
|
->assertHeader('Last-Modified')
|
|
|
|
->assertHeader('Accept-Ranges', 'bytes')
|
|
|
|
->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash))
|
|
|
|
->assertSuccessful();
|
2018-07-22 10:00:30 +08:00
|
|
|
|
|
|
|
Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception);
|
|
|
|
$this->get('/textures/'.$steve->hash)->assertNotFound();
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testTextureWithApi()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
Storage::disk('textures')->put($steve->hash, '');
|
|
|
|
|
|
|
|
$this->get('/csl/textures/'.$steve->hash)
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png')
|
|
|
|
->assertHeader('Last-Modified')
|
|
|
|
->assertHeader('Accept-Ranges', 'bytes')
|
|
|
|
->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash))
|
|
|
|
->assertStatus(200);
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$this->get('/usm/textures/'.$steve->hash)
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png')
|
|
|
|
->assertHeader('Last-Modified')
|
|
|
|
->assertHeader('Accept-Ranges', 'bytes')
|
|
|
|
->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash))
|
|
|
|
->assertSuccessful();
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSkin()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
$player = factory(Player::class)->create([
|
|
|
|
'preference' => 'slim',
|
|
|
|
'tid_steve' => $steve->tid,
|
|
|
|
'tid_alex' => 0
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->get("/skin/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.texture-not-uploaded', ['type' => 'alex']));
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$player->setPreference('default');
|
|
|
|
$this->get("/skin/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.texture-deleted'));
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
Storage::disk('textures')->put($steve->hash, '');
|
|
|
|
$this->get("/skin/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png')
|
|
|
|
->assertHeader('Last-Modified')
|
|
|
|
->assertHeader('Accept-Ranges', 'bytes')
|
|
|
|
->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash))
|
|
|
|
->assertSuccessful();
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSkinWithModel()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
$player = factory(Player::class)->create([
|
|
|
|
'preference' => 'slim',
|
|
|
|
'tid_steve' => $steve->tid,
|
|
|
|
'tid_alex' => 0
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->get("/skin/alex/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.texture-not-uploaded', ['type' => 'alex']));
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$player->setPreference('default');
|
|
|
|
$this->get("/skin/steve/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.texture-deleted'));
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testCape()
|
|
|
|
{
|
|
|
|
$cape = factory(Texture::class, 'cape')->create();
|
|
|
|
$player = factory(Player::class)->create([
|
|
|
|
'tid_cape' => $cape->tid
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->get("/cape/{$player->player_name}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('general.texture-deleted'));
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
2018-07-30 15:13:14 +08:00
|
|
|
public function testAvatarByTid()
|
|
|
|
{
|
|
|
|
$this->get('/avatar/1')->assertHeader('Content-Type', 'image/png');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testAvatarByTidWithSize()
|
|
|
|
{
|
|
|
|
$this->get('/avatar/50/1')->assertHeader('Content-Type', 'image/png');
|
|
|
|
}
|
|
|
|
|
2017-11-17 07:40:29 +08:00
|
|
|
public function testAvatar()
|
|
|
|
{
|
|
|
|
$base64_email = base64_encode('a@b.c');
|
|
|
|
$this->get("/avatar/$base64_email.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$steve = factory(Texture::class)->create();
|
2018-02-23 23:17:29 +08:00
|
|
|
$png = base64_decode(\App\Http\Controllers\TextureController::getDefaultSteveSkin());
|
2017-11-17 07:40:29 +08:00
|
|
|
Storage::disk('textures')->put($steve->hash, $png);
|
|
|
|
|
|
|
|
$user = factory(User::class)->create(['avatar' => $steve->tid]);
|
|
|
|
|
|
|
|
$mock = Mockery::mock('overload:Minecraft');
|
|
|
|
$mock->shouldReceive('generateAvatarFromSkin')
|
|
|
|
->once()
|
|
|
|
->andReturn(imagecreatefromstring($png));
|
|
|
|
|
|
|
|
$this->expectsEvents(\App\Events\GetAvatarPreview::class);
|
|
|
|
$this->get('/avatar/'.base64_encode($user->email).'.png')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2018-07-22 10:00:30 +08:00
|
|
|
|
|
|
|
Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception);
|
|
|
|
$this->get('/avatar/'.base64_encode($user->email).'.png')
|
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testAvatarWithSize()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
2018-02-23 23:17:29 +08:00
|
|
|
$png = base64_decode(\App\Http\Controllers\TextureController::getDefaultSteveSkin());
|
2017-11-17 07:40:29 +08:00
|
|
|
Storage::disk('textures')->put($steve->hash, $png);
|
|
|
|
|
|
|
|
$user = factory(User::class)->create(['avatar' => $steve->tid]);
|
|
|
|
|
|
|
|
$mock = Mockery::mock('overload:Minecraft');
|
|
|
|
$mock->shouldReceive('generateAvatarFromSkin')
|
|
|
|
->once()
|
|
|
|
->andReturn(imagecreatefromstring($png));
|
|
|
|
|
|
|
|
$this->expectsEvents(\App\Events\GetAvatarPreview::class);
|
|
|
|
$this->get('/avatar/50/'.base64_encode($user->email).'.png')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testPreview()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
$cape = factory(Texture::class, 'cape')->create();
|
|
|
|
|
|
|
|
$this->get('/preview/0.png')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$this->get("/preview/{$steve->tid}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
2018-02-23 23:17:29 +08:00
|
|
|
$png = base64_decode(\App\Http\Controllers\TextureController::getDefaultSteveSkin());
|
2017-11-17 07:40:29 +08:00
|
|
|
Storage::disk('textures')->put($steve->hash, $png);
|
|
|
|
Storage::disk('textures')->put($cape->hash, $png);
|
|
|
|
|
|
|
|
$mock = Mockery::mock('overload:Minecraft');
|
|
|
|
$mock->shouldReceive('generatePreviewFromSkin')
|
|
|
|
->once()
|
|
|
|
->andReturn(imagecreatefromstring($png));
|
|
|
|
$this->expectsEvents(\App\Events\GetSkinPreview::class);
|
|
|
|
$this->get("/preview/{$steve->tid}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
$mock->shouldReceive('generatePreviewFromCape')
|
|
|
|
->once()
|
|
|
|
->andReturn(imagecreatefromstring($png));
|
|
|
|
$this->get("/preview/{$cape->tid}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2018-07-22 10:00:30 +08:00
|
|
|
|
|
|
|
Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception);
|
|
|
|
$this->get("/preview/{$steve->tid}.png")
|
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testPreviewWithSize()
|
|
|
|
{
|
|
|
|
$this->get('/preview/200/0.png')
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testRaw()
|
|
|
|
{
|
|
|
|
$steve = factory(Texture::class)->create();
|
|
|
|
Storage::disk('textures')->put($steve->hash, '');
|
|
|
|
|
|
|
|
// Not found
|
|
|
|
$this->get('/raw/0.png')
|
2018-07-22 10:00:30 +08:00
|
|
|
->assertNotFound()
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertSee(trans('skinlib.non-existent'));
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
// Success
|
|
|
|
$this->get("/raw/{$steve->tid}.png")
|
2018-07-13 15:21:13 +08:00
|
|
|
->assertHeader('Content-Type', 'image/png');
|
2017-11-17 07:40:29 +08:00
|
|
|
|
|
|
|
// Texture is deleted
|
|
|
|
Storage::disk('textures')->delete($steve->hash);
|
2018-07-22 09:38:42 +08:00
|
|
|
$this->get("/raw/{$steve->tid}.png")->assertNotFound();
|
|
|
|
|
|
|
|
// Disallow downloading texture directly
|
2018-07-22 10:34:24 +08:00
|
|
|
option(['allow_downloading_texture' => false]);
|
2018-07-22 09:38:42 +08:00
|
|
|
$this->get("/raw/{$steve->tid}.png")->assertNotFound();
|
2017-11-17 07:40:29 +08:00
|
|
|
}
|
|
|
|
}
|