blessing-skin-server/tests/SkinlibControllerTest.php

974 lines
35 KiB
PHP
Raw Normal View History

2017-11-24 18:54:30 +08:00
<?php
2018-08-17 15:25:08 +08:00
namespace Tests;
2017-11-24 18:54:30 +08:00
use App\Models\User;
use App\Models\Player;
use App\Models\Texture;
2019-02-27 23:44:50 +08:00
use Illuminate\Support\Str;
2017-11-24 18:54:30 +08:00
use Illuminate\Http\UploadedFile;
2018-08-17 15:25:08 +08:00
use Illuminate\Support\Facades\Storage;
2017-11-24 18:54:30 +08:00
use Illuminate\Foundation\Testing\DatabaseTransactions;
class SkinlibControllerTest extends TestCase
{
use DatabaseTransactions;
public function testIndex()
{
2018-07-13 19:02:16 +08:00
$this->get('/skinlib')->assertViewHas('user');
2017-11-24 18:54:30 +08:00
}
public function testGetSkinlibFiltered()
{
2018-07-13 19:02:16 +08:00
$this->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2017-11-24 18:54:30 +08:00
'items' => [],
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 0,
2019-04-23 19:14:41 +08:00
]]);
2017-11-24 18:54:30 +08:00
$steves = factory(Texture::class)->times(5)->create();
$alexs = factory(Texture::class, 'alex')->times(5)->create();
$skins = $steves->merge($alexs);
$capes = factory(Texture::class, 'cape')->times(5)->create();
// Default arguments
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(10, $items);
$this->assertTrue(collect($items)->every(function ($item) {
return $item['type'] == 'steve' || $item['type'] == 'alex';
}));
2017-11-24 18:54:30 +08:00
// Only steve
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?filter=steve')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(5, $items);
$this->assertTrue(collect($items)->every(function ($item) {
return $item['type'] == 'steve';
}));
2017-11-24 18:54:30 +08:00
// Invalid type
2018-07-13 19:02:16 +08:00
$this->getJson('/skinlib/data?filter=what')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2017-11-24 18:54:30 +08:00
'items' => [],
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 0,
2019-04-23 19:14:41 +08:00
]]);
2017-11-24 18:54:30 +08:00
// Only capes
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?filter=cape')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(5, $items);
$this->assertTrue(collect($items)->every(function ($item) {
return $item['type'] == 'cape';
}));
2017-11-24 18:54:30 +08:00
// Only specified uploader
$uid = $skins->random()->uploader;
2019-03-14 23:55:49 +08:00
$owned = $skins
2017-11-24 18:54:30 +08:00
->filter(function ($texture) use ($uid) {
return $texture->uploader == $uid;
2019-03-14 23:55:49 +08:00
});
$items = $this->getJson('/skinlib/data?uploader='.$uid)
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount($owned->count(), $items);
$this->assertTrue(collect($items)->every(function ($item) use ($uid) {
return $item['uploader'] == $uid;
}));
2017-11-24 18:54:30 +08:00
2018-07-15 18:34:38 +08:00
// Sort by `tid`
2019-03-14 23:55:49 +08:00
$ordered = $skins->sortByDesc('tid')->map(function ($skin) {
return $skin->tid;
})->values();
$items = $this->getJson('/skinlib/data?sort=tid')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$items = array_map(function ($item) {
return $item['tid'];
}, $items);
$this->assertArraySubset($ordered, $items);
2017-11-24 18:54:30 +08:00
2019-03-19 15:19:33 +08:00
// Sort by `likes`
$user = factory(User::class)->create();
$user->closet()->attach($skins->random()->tid, ['item_name' => 'name']);
$items = $this->getJson('/skinlib/data?sort=likes')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2019-03-19 15:19:33 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:19:33 +08:00
$this->assertEquals(1, $items[0]['likes']);
$this->assertEquals(0, $items[1]['likes']);
2017-11-24 18:54:30 +08:00
// Search
2019-02-27 23:44:50 +08:00
$keyword = Str::limit($skins->random()->name, 1, '');
2019-03-14 23:55:49 +08:00
$keyworded = $skins
2017-11-24 18:54:30 +08:00
->filter(function ($texture) use ($keyword) {
2019-02-27 23:44:50 +08:00
return Str::contains($texture->name, $keyword) ||
Str::contains($texture->name, strtolower($keyword));
2019-03-14 23:55:49 +08:00
});
$items = $this->getJson('/skinlib/data?keyword='.$keyword)
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount($keyworded->count(), $items);
2017-11-24 18:54:30 +08:00
// More than one argument
2019-02-27 23:44:50 +08:00
$keyword = Str::limit($skins->random()->name, 1, '');
2019-03-14 23:55:49 +08:00
$filtered = $skins
2017-11-24 18:54:30 +08:00
->filter(function ($texture) use ($keyword) {
2019-02-27 23:44:50 +08:00
return Str::contains($texture->name, $keyword) ||
Str::contains($texture->name, strtolower($keyword));
2017-11-24 18:54:30 +08:00
})
2019-03-14 23:55:49 +08:00
->sortByDesc('size')
->map(function ($skin) {
return $skin->tid;
})
2017-11-24 18:54:30 +08:00
->values();
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?sort=size&keyword='.$keyword)
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 1,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$items = array_map(function ($item) {
return $item['tid'];
}, $items);
$this->assertCount($filtered->count(), $items);
$this->assertArraySubset($filtered, $items);
2017-11-24 18:54:30 +08:00
// Pagination
$steves = factory(Texture::class)
->times(15)
->create()
->merge($steves);
$skins = $steves->merge($alexs);
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(20, $items);
$items = $this->getJson('/skinlib/data?page=-5')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(20, $items);
2019-03-19 15:30:52 +08:00
$page2Count = $skins->forPage(2, 20)->count();
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?page=2')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertCount(5, $items);
2018-07-13 19:02:16 +08:00
$this->getJson('/skinlib/data?page=8')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2017-11-24 18:54:30 +08:00
'items' => [],
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]]);
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?items_per_page=-6&page=2')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:30:52 +08:00
$this->assertCount($page2Count, $items);
$page3Count = $skins->forPage(3, 8)->count();
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data?page=3&items_per_page=8')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 4,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:30:52 +08:00
$this->assertCount($page3Count, $items);
2017-11-24 18:54:30 +08:00
// Add some private textures
$uploader = factory(User::class)->create();
$otherUser = factory(User::class)->create();
$private = factory(Texture::class)
->times(5)
->create(['public' => false, 'uploader' => $uploader->uid]);
// If not logged in, private textures should not be shown
2019-03-14 23:55:49 +08:00
$items = $this->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => 0,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:30:52 +08:00
$this->assertTrue(collect($items)->every(function ($item) {
return $item['public'] == true;
}));
2017-11-24 18:54:30 +08:00
// Other users should not see someone's private textures
2019-04-04 09:50:48 +08:00
$items = $this->actingAs($otherUser)
2018-07-13 19:02:16 +08:00
->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => $otherUser->uid,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-14 23:55:49 +08:00
$this->assertTrue(collect($items)->every(function ($item) {
2019-03-15 00:09:39 +08:00
return ! $item['liked'];
2019-03-14 23:55:49 +08:00
}));
2017-11-24 18:54:30 +08:00
// A user has added a texture from skin library to his closet
2019-03-14 23:55:49 +08:00
$texture = $skins->sortByDesc('upload_at')->values()->first();
$otherUser->closet()->attach($texture->tid, ['item_name' => $texture->name]);
2018-07-13 19:02:16 +08:00
$this->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2019-03-14 23:55:49 +08:00
'items' => [
2019-03-15 00:09:39 +08:00
['tid' => $texture->tid, 'liked' => true],
2019-03-14 23:55:49 +08:00
],
2018-08-14 23:27:36 +08:00
'current_uid' => $otherUser->uid,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]]);
2017-11-24 18:54:30 +08:00
// Uploader can see his private textures
2019-04-04 09:50:48 +08:00
$items = $this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => $uploader->uid,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:30:52 +08:00
$this->assertTrue(collect($items)->contains(function ($item) {
return $item['public'] == false;
}));
2017-11-24 18:54:30 +08:00
// Administrators can see private textures
$admin = factory(User::class, 'admin')->create();
2019-04-04 09:50:48 +08:00
$items = $this->actingAs($admin)
2018-07-13 19:02:16 +08:00
->getJson('/skinlib/data')
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2018-08-14 23:27:36 +08:00
'current_uid' => $admin->uid,
'total_pages' => 2,
2019-04-23 19:14:41 +08:00
]])
->decodeResponseJson('data')['items'];
2019-03-19 15:30:52 +08:00
$this->assertTrue(collect($items)->contains(function ($item) {
return $item['public'] == false;
}));
2017-11-24 18:54:30 +08:00
}
public function testShow()
{
2019-03-14 00:02:00 +08:00
Storage::fake('textures');
2017-11-24 18:54:30 +08:00
// Cannot find texture
$this->get('/skinlib/show/1')
2018-07-13 19:02:16 +08:00
->assertSee(trans('skinlib.show.deleted'));
2017-11-24 18:54:30 +08:00
// Invalid texture
option(['auto_del_invalid_texture' => false]);
$texture = factory(Texture::class)->create();
$this->get('/skinlib/show/'.$texture->tid)
2018-07-13 19:02:16 +08:00
->assertSee(trans('skinlib.show.deleted').trans('skinlib.show.contact-admin'));
2017-11-24 18:54:30 +08:00
$this->assertNotNull(Texture::find($texture->tid));
option(['auto_del_invalid_texture' => true]);
$this->get('/skinlib/show/'.$texture->tid)
2018-07-13 19:02:16 +08:00
->assertSee(trans('skinlib.show.deleted'));
2017-11-24 18:54:30 +08:00
$this->assertNull(Texture::find($texture->tid));
// Show a texture
$texture = factory(Texture::class)->create();
Storage::disk('textures')->put($texture->hash, '');
$this->get('/skinlib/show/'.$texture->tid)
->assertViewHas('texture')
->assertViewHas('with_out_filter', true)
->assertViewHas('user');
// Guest should not see private texture
$uploader = factory(User::class)->create();
$texture = factory(Texture::class)->create([
'uploader' => $uploader->uid,
'public' => false,
2017-11-24 18:54:30 +08:00
]);
Storage::disk('textures')->put($texture->hash, '');
$this->get('/skinlib/show/'.$texture->tid)
2018-07-13 19:02:16 +08:00
->assertSee(trans('skinlib.show.private'));
2017-11-24 18:54:30 +08:00
// Other user should not see private texture
$this->actAs('normal')
->get('/skinlib/show/'.$texture->tid)
2018-07-13 19:02:16 +08:00
->assertSee(trans('skinlib.show.private'));
2017-11-24 18:54:30 +08:00
// Administrators should be able to see private textures
$this->actAs('admin')
->get('/skinlib/show/'.$texture->tid)
->assertViewHas('texture');
// Uploader should be able to see private textures
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2017-11-24 18:54:30 +08:00
->get('/skinlib/show/'.$texture->tid)
->assertViewHas('texture');
}
public function testInfo()
{
// Non-existed texture
2019-04-23 19:14:41 +08:00
$this->get('/skinlib/info/1')->assertNotFound();
2017-11-24 18:54:30 +08:00
$texture = factory(Texture::class)->create();
$this->get('/skinlib/info/'.$texture->tid)
2019-04-23 19:14:41 +08:00
->assertJson(['data' => [
2017-11-24 18:54:30 +08:00
'tid' => $texture->tid,
'name' => $texture->name,
'type' => $texture->type,
'likes' => $texture->likes,
'hash' => $texture->hash,
'size' => $texture->size,
'uploader' => $texture->uploader,
2018-07-16 11:10:01 +08:00
'public' => $texture->public,
'upload_at' => $texture->upload_at->format('Y-m-d H:i:s'),
2019-04-23 19:14:41 +08:00
]]);
2017-11-24 18:54:30 +08:00
}
public function testUpload()
{
$this->actAs('normal')
2018-07-13 19:02:16 +08:00
->get('/skinlib/upload')
2017-11-24 18:54:30 +08:00
->assertViewHas('user')
->assertViewHas('with_out_filter', true);
2019-04-06 23:16:14 +08:00
option(['texture_name_regexp' => 'abc']);
$this->get('/skinlib/upload')->assertViewHas('extra');
2017-11-24 18:54:30 +08:00
}
public function testHandleUpload()
{
2018-07-13 19:02:16 +08:00
Storage::fake('textures');
2017-11-24 18:54:30 +08:00
// Some error occurred when uploading file
2019-03-14 00:02:00 +08:00
$file = UploadedFile::fake()->image('test.png');
2017-11-24 18:54:30 +08:00
$upload = new UploadedFile(
2019-03-14 00:02:00 +08:00
$file->path(),
'test.png',
2017-11-24 18:54:30 +08:00
'image/png',
50,
UPLOAD_ERR_NO_TMP_DIR,
true
);
$this->actAs('normal')
2018-07-13 19:02:16 +08:00
->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
['file' => $upload]
2018-07-13 19:02:16 +08:00
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => UPLOAD_ERR_NO_TMP_DIR,
'message' => \App\Http\Controllers\SkinlibController::$phpFileUploadErrors[UPLOAD_ERR_NO_TMP_DIR],
2018-07-13 19:02:16 +08:00
]);
2017-11-24 18:54:30 +08:00
// Without `name` field
$this->postJson('/skinlib/upload')->assertJsonValidationErrors('name');
2017-11-24 18:54:30 +08:00
// With some special chars
2019-03-14 00:30:53 +08:00
$this->postJson('/skinlib/upload', ['name' => '\\'])
->assertJsonValidationErrors('name');
2017-11-24 18:54:30 +08:00
// Specified regular expression for texture name
option(['texture_name_regexp' => '/\\d+/']);
$this->postJson('/skinlib/upload', [
'name' => 'abc',
])->assertJsonValidationErrors('name');
option(['texture_name_regexp' => null]);
2017-11-24 18:54:30 +08:00
// Without file
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/upload', [
'name' => 'texture',
])->assertJsonValidationErrors('file');
2017-11-24 18:54:30 +08:00
// Too large file
option(['max_upload_file_size' => 2]);
2018-07-13 19:02:16 +08:00
$upload = UploadedFile::fake()->create('large.png', 5);
$this->postJson('/skinlib/upload', [
2017-11-24 18:54:30 +08:00
'name' => 'texture',
'file' => $upload,
])->assertJsonValidationErrors('file');
2017-11-24 18:54:30 +08:00
option(['max_upload_file_size' => 1024]);
// Without `public` field
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/upload', [
2017-11-24 18:54:30 +08:00
'name' => 'texture',
'file' => 'content', // Though it is not a file, it is OK
])->assertJsonValidationErrors('public');
2017-11-24 18:54:30 +08:00
// Not a PNG image
2018-07-13 19:02:16 +08:00
$this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
2018-07-13 19:02:16 +08:00
'public' => 'true',
'file' => UploadedFile::fake()->create('fake', 5),
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.upload.type-error'),
2017-11-24 18:54:30 +08:00
]);
// No texture type is specified
2018-07-13 19:02:16 +08:00
$this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
2018-07-13 19:02:16 +08:00
'public' => 'true',
'file' => UploadedFile::fake()->image('texture.png', 64, 32),
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('general.illegal-parameters'),
2017-11-24 18:54:30 +08:00
]);
// Invalid skin size
2018-07-13 19:02:16 +08:00
$this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'true',
2018-07-13 19:02:16 +08:00
'type' => 'steve',
'file' => UploadedFile::fake()->image('texture.png', 64, 30),
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans(
2017-11-24 18:54:30 +08:00
'skinlib.upload.invalid-size',
[
'type' => trans('general.skin'),
'width' => 64,
'height' => 30,
2017-11-24 18:54:30 +08:00
]
),
2017-11-24 18:54:30 +08:00
]);
2018-07-13 19:02:16 +08:00
$this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'true',
2018-07-13 19:02:16 +08:00
'type' => 'alex',
'file' => UploadedFile::fake()->image('texture.png', 100, 50),
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans(
2017-11-24 18:54:30 +08:00
'skinlib.upload.invalid-hd-skin',
[
'type' => trans('general.skin'),
'width' => 100,
'height' => 50,
2017-11-24 18:54:30 +08:00
]
),
2017-11-24 18:54:30 +08:00
]);
2018-07-13 19:02:16 +08:00
$this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'true',
2018-07-13 19:02:16 +08:00
'type' => 'cape',
'file' => UploadedFile::fake()->image('texture.png', 64, 30),
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans(
2017-11-24 18:54:30 +08:00
'skinlib.upload.invalid-size',
[
'type' => trans('general.cape'),
'width' => 64,
'height' => 30,
2017-11-24 18:54:30 +08:00
]
),
2017-11-24 18:54:30 +08:00
]);
2018-07-13 19:02:16 +08:00
$upload = UploadedFile::fake()->image('texture.png', 64, 32);
2017-11-24 18:54:30 +08:00
// Score is not enough
$user = factory(User::class)->create(['score' => 0]);
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
2018-07-13 19:02:16 +08:00
->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
2018-07-13 19:02:16 +08:00
'public' => 'true',
'type' => 'steve',
'file' => $upload,
2018-07-13 19:02:16 +08:00
]
)
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 7,
'message' => trans('skinlib.upload.lack-score'),
2018-07-13 19:02:16 +08:00
]);
$user = factory(User::class)->create([
'score' => (int) option('score_per_closet_item') + (int) option('score_per_storage'),
2018-07-13 19:02:16 +08:00
]);
2019-04-04 09:50:48 +08:00
$this->actingAs($user)->postJson(
2018-07-13 19:02:16 +08:00
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'false', // Private texture cost more scores
'type' => 'steve',
'file' => $upload,
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 7,
'message' => trans('skinlib.upload.lack-score'),
2017-11-24 18:54:30 +08:00
]);
2019-03-20 23:28:04 +08:00
// Success
option(['score_award_per_texture' => 2]);
2018-07-13 19:02:16 +08:00
$response = $this->postJson(
2017-11-24 18:54:30 +08:00
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'true', // Public texture
2018-07-13 19:02:16 +08:00
'type' => 'steve',
'file' => $upload,
2018-07-13 19:02:16 +08:00
]
2017-11-24 18:54:30 +08:00
);
2018-07-13 19:02:16 +08:00
$t = Texture::where('name', 'texture')->first();
$response->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.upload.success', ['name' => 'texture']),
2019-04-23 19:14:41 +08:00
'data' => ['tid' => $t->tid],
2017-11-24 18:54:30 +08:00
]);
2018-07-13 19:02:16 +08:00
Storage::disk('textures')->assertExists($t->hash);
$user = User::find($user->uid);
2019-03-20 23:28:04 +08:00
$this->assertEquals(2, $user->score);
2018-07-13 19:02:16 +08:00
$this->assertEquals('texture', $t->name);
$this->assertEquals('steve', $t->type);
$this->assertEquals(1, $t->likes);
$this->assertEquals(1, $t->size);
$this->assertEquals($user->uid, $t->uploader);
2018-07-16 11:10:01 +08:00
$this->assertTrue($t->public);
2017-11-24 18:54:30 +08:00
// Upload a duplicated texture
2018-07-13 19:02:16 +08:00
$user = factory(User::class)->create();
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
2018-07-13 19:02:16 +08:00
->postJson(
'/skinlib/upload',
[
'name' => 'texture',
'public' => 'true',
'type' => 'steve',
'file' => $upload,
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.upload.repeated'),
2019-04-23 19:14:41 +08:00
'data' => ['tid' => $t->tid],
2018-07-13 19:02:16 +08:00
]);
unlink(storage_path('framework/testing/disks/textures/'.$t->hash));
2017-11-24 18:54:30 +08:00
}
public function testDelete()
{
$uploader = factory(User::class)->create();
$other = factory(User::class)->create();
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
option(['return_score' => false]);
// Non-existed texture
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/delete', ['tid' => -1])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.non-existent'),
2017-11-24 18:54:30 +08:00
]);
// Other user should not be able to delete
2019-04-04 09:50:48 +08:00
$this->actingAs($other)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.no-permission'),
2017-11-24 18:54:30 +08:00
]);
// Administrators can delete it
$this->actAs('admin')
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
$this->assertNull(Texture::find($texture->tid));
$texture = factory(Texture::class)->create();
factory(Texture::class)->create(['hash' => $texture->hash]);
Storage::disk('textures')->put($texture->hash, '');
// When file is occupied, the file should not be deleted
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
$this->assertNull(Texture::find($texture->tid));
$this->assertTrue(Storage::disk('textures')->exists($texture->hash));
$texture = factory(Texture::class)->create();
factory(Texture::class)->create(['hash' => $texture->hash]);
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
$this->assertNull(Texture::find($texture->tid));
$this->assertFalse(Storage::disk('textures')->exists($texture->hash));
// Return score
option(['return_score' => true]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(
$uploader->score + $texture->size * option('score_per_storage'),
User::find($uploader->uid)->score
);
$uploader = User::find($uploader->uid);
$texture = factory(Texture::class)->create([
'uploader' => $uploader->uid,
'public' => false,
2017-11-24 18:54:30 +08:00
]);
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(
$uploader->score + $texture->size * option('private_score_per_storage'),
User::find($uploader->uid)->score
);
2019-03-20 23:28:04 +08:00
option(['return_score' => false]);
// Return the award
option(['score_award_per_texture' => 5]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$uploader->refresh();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2019-03-20 23:28:04 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2019-03-20 23:28:04 +08:00
$this->assertEquals($uploader->score - 5, User::find($uploader->uid)->score);
// Option disabled
option(['take_back_scores_after_deletion' => false]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$uploader->refresh();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2019-03-20 23:28:04 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2019-03-20 23:28:04 +08:00
$this->assertEquals($uploader->score, User::find($uploader->uid)->score);
// Private texture
$texture = factory(Texture::class)->create([
'uploader' => $uploader->uid,
2019-04-19 19:36:36 +08:00
'public' => false,
2019-03-20 23:28:04 +08:00
]);
$uploader->refresh();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2019-03-20 23:28:04 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2019-03-20 23:28:04 +08:00
$this->assertEquals($uploader->score, User::find($uploader->uid)->score);
// Remove from closet
option(['return_score' => true]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$other->closet()->attach($texture->tid, ['item_name' => 'a']);
$other->score = 0;
$other->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2019-03-20 23:28:04 +08:00
->postJson('/skinlib/delete', ['tid' => $texture->tid])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2019-03-20 23:28:04 +08:00
$other->refresh();
$this->assertEquals(option('score_per_closet_item'), $other->score);
2017-11-24 18:54:30 +08:00
}
public function testPrivacy()
{
$uploader = factory(User::class)->create();
$other = factory(User::class)->create();
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
// Non-existed texture
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/privacy', ['tid' => -1])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.non-existent'),
2017-11-24 18:54:30 +08:00
]);
// Other user should not be able to set privacy
2019-04-04 09:50:48 +08:00
$this->actingAs($other)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/privacy', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.no-permission'),
2017-11-24 18:54:30 +08:00
]);
// Administrators can change it
$uploader->score += $texture->size * option('private_score_per_storage');
$uploader->save();
$this->actAs('admin')
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/privacy', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.privacy.success', ['privacy' => trans('general.private')]),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(0, Texture::find($texture->tid)->public);
// Setting a texture to be private needs more scores
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$uploader->score = 0;
$uploader->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/privacy', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.upload.lack-score'),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(1, Texture::find($texture->tid)->public);
$texture->public = true;
$texture->save();
$uploader->score = $texture->size *
(option('private_score_per_storage') - option('score_per_storage'));
$uploader->save();
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/privacy', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.privacy.success', ['privacy' => trans('general.private')]),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(0, User::find($uploader->uid)->score);
// When setting a texture to be private,
// other players should not be able to use it.
2018-07-14 08:27:15 +08:00
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
$uploader->score += $texture->size * option('private_score_per_storage');
$uploader->save();
$player = factory(Player::class)->create(['tid_skin' => $texture->tid]);
2019-03-14 23:55:49 +08:00
$other = factory(User::class)->create();
$other->closet()->attach($texture->tid, ['item_name' => 'a']);
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/privacy', ['tid' => $texture->tid])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.privacy.success', ['privacy' => trans('general.private')]),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals(0, Player::find($player->pid)->tid_skin);
2019-03-14 23:55:49 +08:00
$this->assertEquals(0, $other->closet()->count());
$this->assertEquals(
$other->score + option('score_per_closet_item'),
User::find($other->uid)->score
);
2019-03-20 23:28:04 +08:00
// Take back the score
option(['score_award_per_texture' => 5]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$uploader->score = $texture->size * (
option('private_score_per_storage') - option('score_per_storage')
);
$uploader->score += option('score_award_per_texture');
$uploader->save();
$this->postJson('/skinlib/privacy', ['tid' => $texture->tid])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2019-03-20 23:28:04 +08:00
$this->assertEquals(0, User::find($uploader->uid)->score);
2019-03-14 23:55:49 +08:00
// Without returning score
2019-03-16 09:56:31 +08:00
option(['return_score' => false, 'private_score_per_storage' => 0]);
2019-03-14 23:55:49 +08:00
$texture = factory(Texture::class)->create(['public' => 'false', 'uploader' => $uploader->uid]);
$other = factory(User::class)->create();
$other->closet()->attach($texture->tid, ['item_name' => 'a']);
$this->postJson('/skinlib/privacy', ['tid' => $texture->tid])
2019-04-23 19:14:41 +08:00
->assertJson(['code' => 0]);
2019-03-16 09:56:31 +08:00
$this->assertEquals($other->score, User::find($other->uid)->score);
2017-11-24 18:54:30 +08:00
}
public function testRename()
{
$uploader = factory(User::class)->create();
$other = factory(User::class)->create();
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
// Without `tid` field
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2019-03-14 00:30:53 +08:00
->postJson('/skinlib/rename')
->assertJsonValidationErrors('tid');
2017-11-24 18:54:30 +08:00
// `tid` is not a integer
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/rename', [
'tid' => 'str',
2017-11-24 18:54:30 +08:00
])
->assertJsonValidationErrors('tid');
2017-11-24 18:54:30 +08:00
// Without `new_name` field
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/rename', [
'tid' => $texture->tid,
2017-11-24 18:54:30 +08:00
])
->assertJsonValidationErrors('new_name');
2017-11-24 18:54:30 +08:00
// `new_name` has special chars
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/rename', [
2017-11-24 18:54:30 +08:00
'tid' => $texture->tid,
'new_name' => '\\',
2017-11-24 18:54:30 +08:00
])
->assertJsonValidationErrors('new_name');
2017-11-24 18:54:30 +08:00
// Non-existed texture
2018-07-13 19:02:16 +08:00
$this->postJson('/skinlib/rename', [
2017-11-24 18:54:30 +08:00
'tid' => -1,
'new_name' => 'name',
2017-11-24 18:54:30 +08:00
])
2018-07-13 19:02:16 +08:00
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.non-existent'),
2017-11-24 18:54:30 +08:00
]);
// Other user should not be able to rename
2019-04-04 09:50:48 +08:00
$this->actingAs($other)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/rename', [
2017-11-24 18:54:30 +08:00
'tid' => $texture->tid,
'new_name' => 'name',
2017-11-24 18:54:30 +08:00
])
2018-07-13 19:02:16 +08:00
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.no-permission'),
2017-11-24 18:54:30 +08:00
]);
// Administrators should be able to rename
$this->actAs('admin')
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/rename', [
2017-11-24 18:54:30 +08:00
'tid' => $texture->tid,
'new_name' => 'name',
2017-11-24 18:54:30 +08:00
])
2018-07-13 19:02:16 +08:00
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.rename.success', ['name' => 'name']),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals('name', Texture::find($texture->tid)->name);
// Uploader should be able to rename
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2018-07-13 19:02:16 +08:00
->postJson('/skinlib/rename', [
2017-11-24 18:54:30 +08:00
'tid' => $texture->tid,
'new_name' => 'new_name',
2017-11-24 18:54:30 +08:00
])
2018-07-13 19:02:16 +08:00
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.rename.success', ['name' => 'new_name']),
2017-11-24 18:54:30 +08:00
]);
$this->assertEquals('new_name', Texture::find($texture->tid)->name);
}
public function testModel()
{
$uploader = factory(User::class)->create();
$other = factory(User::class)->create();
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
// Non-existed texture
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
->postJson('/skinlib/model', [
'tid' => -1,
'model' => 'alex',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.non-existent'),
]);
// Other user should not be able to change model
2019-04-04 09:50:48 +08:00
$this->actingAs($other)
->postJson('/skinlib/model', [
'tid' => $texture->tid,
'model' => 'alex',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.no-permission'),
]);
// Administrators should be able to change model
$this->actAs('admin')
->postJson('/skinlib/model', [
'tid' => $texture->tid,
'model' => 'alex',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.model.success', ['model' => 'alex']),
]);
$this->assertEquals('alex', Texture::find($texture->tid)->type);
// Uploader should be able to change model
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
->postJson('/skinlib/model', [
'tid' => $texture->tid,
'model' => 'steve',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.model.success', ['model' => 'steve']),
]);
$this->assertEquals('steve', Texture::find($texture->tid)->type);
$duplicate = factory(Texture::class, 'alex')->create([
'uploader' => $other->uid,
'hash' => $texture->hash,
]);
// Should fail if there is already a texture with same hash and chosen model
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
->postJson('/skinlib/model', [
'tid' => $texture->tid,
'model' => 'alex',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.model.duplicate', ['name' => $duplicate->name]),
]);
// Allow private texture
$duplicate->public = false;
$duplicate->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
->postJson('/skinlib/model', [
'tid' => $texture->tid,
'model' => 'alex',
])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.model.success', ['model' => 'alex']),
]);
}
2017-11-24 18:54:30 +08:00
}