mc-blessing-skin/tests/HttpTest/ControllersTest/SkinlibControllerTest.php

844 lines
29 KiB
PHP
Raw Permalink 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\Texture;
2019-12-14 11:10:37 +08:00
use App\Models\User;
2020-06-04 16:36:10 +08:00
use Blessing\Rejection;
2020-03-24 18:05:46 +08:00
use Carbon\Carbon;
2020-06-04 16:36:10 +08:00
use Illuminate\Filesystem\FilesystemAdapter;
2019-12-14 11:10:37 +08:00
use Illuminate\Foundation\Testing\DatabaseTransactions;
2017-11-24 18:54:30 +08:00
use Illuminate\Http\UploadedFile;
2020-06-04 16:36:10 +08:00
use Illuminate\Support\Facades\Event;
2018-08-17 15:25:08 +08:00
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Image;
2017-11-24 18:54:30 +08:00
class SkinlibControllerTest extends TestCase
{
use DatabaseTransactions;
2020-06-05 23:35:49 +08:00
public function testAccessControl()
{
Storage::fake('textures');
2020-10-14 11:56:34 +08:00
$other = User::factory()->create();
$texture = Texture::factory()->create();
2020-06-05 23:35:49 +08:00
// other user should not be able to delete
$this->actingAs($other)
->deleteJson(route('texture.delete', ['texture' => $texture]))
->assertJson(['code' => 1])
->assertForbidden();
// administrators can delete it
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->admin()->create())
2020-06-05 23:35:49 +08:00
->deleteJson(route('texture.delete', ['texture' => $texture]))
->assertJson(['code' => 0]);
}
2020-03-24 18:05:46 +08:00
public function testLibrary()
2017-11-24 18:54:30 +08:00
{
2020-10-14 11:56:34 +08:00
$steve = Texture::factory()->create([
2020-03-24 18:05:46 +08:00
'name' => 'ab',
'upload_at' => Carbon::now()->subDays(2),
'likes' => 80,
]);
2020-10-14 11:56:34 +08:00
$alex = Texture::factory()->alex()->create([
2020-03-24 18:05:46 +08:00
'name' => 'cd',
'upload_at' => Carbon::now()->subDays(1),
'likes' => 60,
]);
2020-10-14 11:56:34 +08:00
$private = Texture::factory()->private()->create([
2020-03-24 18:05:46 +08:00
'upload_at' => Carbon::now(),
]);
// default
$this->getJson('/skinlib/list')
->assertJson([
'data' => [
['tid' => $alex->tid, 'nickname' => $alex->owner->nickname],
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
],
]);
2017-11-24 18:54:30 +08:00
2020-03-24 18:05:46 +08:00
// with filter
$this->getJson('/skinlib/list?filter=steve')
->assertJson([
'data' => [
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
2019-03-14 23:55:49 +08:00
],
2020-03-24 18:05:46 +08:00
]);
2017-11-24 18:54:30 +08:00
2020-03-24 18:05:46 +08:00
// with keyword
$this->getJson('/skinlib/list?keyword=a')
->assertJson([
'data' => [
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
],
]);
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
2020-04-27 18:46:22 +08:00
$list = $this->actingAs($user)
->getJson('/skinlib/list?keyword=a')
2020-10-14 11:56:34 +08:00
->json('data');
2020-04-27 18:46:22 +08:00
$this->assertCount(1, $list);
2017-11-24 18:54:30 +08:00
2020-03-24 18:05:46 +08:00
// with uploader
$this->getJson('/skinlib/list?uploader='.$steve->uploader)
->assertJson([
'data' => [
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
],
]);
// sort by likes
$this->getJson('/skinlib/list?sort=likes')
->assertJson([
'data' => [
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
['tid' => $alex->tid, 'nickname' => $alex->owner->nickname],
],
]);
// private textures are not available for other user
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->create())
2020-03-24 18:05:46 +08:00
->getJson('/skinlib/list')
->assertJson([
'data' => [
['tid' => $alex->tid, 'nickname' => $alex->owner->nickname],
['tid' => $steve->tid, 'nickname' => $steve->owner->nickname],
],
]);
// private textures are available for uploader
$this->actingAs($private->owner)
->getJson('/skinlib/list')
->assertJson([
'data' => [
['tid' => $private->tid],
['tid' => $alex->tid],
['tid' => $steve->tid],
],
]);
// private textures are available for administrators
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->admin()->create())
2020-03-24 18:05:46 +08:00
->getJson('/skinlib/list')
->assertJson([
'data' => [
['tid' => $private->tid],
['tid' => $alex->tid],
['tid' => $steve->tid],
],
]);
2017-11-24 18:54:30 +08:00
}
public function testShow()
{
2019-03-14 00:02:00 +08:00
Storage::fake('textures');
2019-12-21 10:41:38 +08:00
$filter = Fakes\Filter::fake();
2019-03-14 00:02:00 +08:00
2017-11-24 18:54:30 +08:00
// Invalid texture
option(['auto_del_invalid_texture' => false]);
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create();
2017-11-24 18:54:30 +08:00
$this->get('/skinlib/show/'.$texture->tid)
2020-08-19 17:58:31 +08:00
->assertSee(trans('skinlib.show.deleted'));
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
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create();
2017-11-24 18:54:30 +08:00
Storage::disk('textures')->put($texture->hash, '');
2019-09-18 23:06:48 +08:00
$this->get('/skinlib/show/'.$texture->tid)->assertViewHas('texture');
2019-12-21 10:41:38 +08:00
$filter->assertApplied('grid:skinlib.show');
2017-11-24 18:54:30 +08:00
// Guest should not see private texture
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$texture = Texture::factory()->create([
2017-11-24 18:54:30 +08:00
'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)
->assertForbidden()
->assertSee(trans('skinlib.show.private'));
option(['status_code_for_private' => 404]);
$this->get('/skinlib/show/'.$texture->tid)
->assertNotFound()
->assertSee(trans('skinlib.show.deleted'));
option(['status_code_for_private' => 403]);
2017-11-24 18:54:30 +08:00
// Other user should not see private texture
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->create())
2017-11-24 18:54:30 +08:00
->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
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->admin()->create())
2017-11-24 18:54:30 +08:00
->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');
// Badges.
$uploader->permission = User::ADMIN;
$uploader->save();
$this->get('/skinlib/show/'.$texture->tid)
->assertSee('primary')
->assertSee('STAFF');
$uid = $uploader->uid;
2020-06-03 09:14:47 +08:00
$filter->add('user_badges', function ($badges, $uploader) use ($uid) {
$this->assertEquals($uid, $uploader->uid);
$badges[] = ['text' => 'badge-test', 'color' => 'maroon'];
return $badges;
});
$this->get('/skinlib/show/'.$texture->tid)
->assertSee('badge-test')
->assertSee('maroon');
2017-11-24 18:54:30 +08:00
}
public function testInfo()
{
$this->get(route('texture.info', ['texture' => 0]))
->assertNotFound()
->assertSee(trans('skinlib.non-existent'));
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create();
2020-06-05 23:35:49 +08:00
$this->get(route('texture.info', ['texture' => $texture]))
2020-06-04 18:12:58 +08:00
->assertJson($texture->toArray());
2017-11-24 18:54:30 +08:00
}
public function testUpload()
{
2019-12-21 10:41:38 +08:00
$filter = Fakes\Filter::fake();
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->create())->get('/skinlib/upload');
2019-12-21 10:41:38 +08:00
$filter->assertApplied('grid:skinlib.upload');
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()
{
2020-06-04 16:36:10 +08:00
Event::fake();
/** @var FilesystemAdapter */
$disk = Storage::fake('textures');
$filter = Fakes\Filter::fake();
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
2018-07-13 19:02:16 +08:00
2020-06-04 16:36:10 +08:00
// without file
$this->actingAs($user)
2020-06-05 23:35:49 +08:00
->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'name',
'type' => 'steve',
'public' => true,
])->assertJsonValidationErrors('file');
// 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',
UPLOAD_ERR_NO_TMP_DIR,
true
);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'name',
'file' => $upload,
'type' => 'steve',
'public' => true,
])->assertJsonValidationErrors('file');
2017-11-24 18:54:30 +08:00
2020-06-04 16:36:10 +08:00
// without `name` field
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'))
->assertJsonValidationErrors('name');
2017-11-24 18:54:30 +08:00
2020-06-04 16:36:10 +08:00
// specified regular expression for texture name
option(['texture_name_regexp' => '/\\d+/']);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), ['name' => 'abc'])
2020-06-04 16:36:10 +08:00
->assertJsonValidationErrors('name');
option(['texture_name_regexp' => null]);
2020-06-04 16:36:10 +08:00
// not a PNG file
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
'name' => 'texture',
2020-06-04 16:36:10 +08:00
'file' => UploadedFile::fake()->create('fake', 5),
])->assertJsonValidationErrors('file');
2017-11-24 18:54:30 +08:00
2020-06-04 16:36:10 +08:00
// too large file
2017-11-24 18:54:30 +08:00
option(['max_upload_file_size' => 2]);
2018-07-13 19:02:16 +08:00
$upload = UploadedFile::fake()->create('large.png', 5);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.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]);
2020-06-04 16:36:10 +08:00
// no texture type is specified
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2017-11-24 18:54:30 +08:00
'name' => 'texture',
2020-06-04 16:36:10 +08:00
'file' => $file,
])->assertJsonValidationErrors('type');
2017-11-24 18:54:30 +08:00
2020-06-04 16:36:10 +08:00
// invalid texture type
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'file' => $file,
'type' => 'nope',
])->assertJsonValidationErrors('type');
2017-11-24 18:54:30 +08:00
2020-06-04 16:36:10 +08:00
// without `public` field
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'file' => $file,
'type' => 'steve',
])->assertJsonValidationErrors('public');
2017-11-24 18:54:30 +08:00
// too wide texture
option(['max_texture_width' => 128]);
$this->postJson(route('texture.upload'), [
'name' => 'texture',
'file' => UploadedFile::fake()->image('wide.png', 256, 256),
'type' => 'steve',
'public' => true,
])->assertJson([
'code' => 1,
'message' => trans('skinlib.upload.too-wide', [
'width' => 256,
'maxWidth' => 128,
]),
]);
option(['max_texture_width' => 8192]);
2020-06-04 16:36:10 +08:00
// invalid skin size
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'public' => true,
'type' => 'steve',
'file' => UploadedFile::fake()->image('texture.png', 64, 30),
])->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
2020-06-04 16:36:10 +08:00
'message' => trans('skinlib.upload.invalid-size', [
'type' => trans('general.skin'),
'width' => 64,
'height' => 30,
]),
2017-11-24 18:54:30 +08:00
]);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'public' => true,
'type' => 'alex',
2021-02-13 15:19:12 +08:00
'file' => UploadedFile::fake()->image('texture.png', 64, 32),
])->assertJson([
'code' => 1,
'message' => trans('skinlib.upload.invalid-size', [
'type' => trans('general.skin'),
'width' => 64,
'height' => 32,
]),
]);
$this->postJson(route('texture.upload'), [
'name' => 'texture',
'public' => true,
'type' => 'steve',
2020-06-04 16:36:10 +08:00
'file' => UploadedFile::fake()->image('texture.png', 100, 50),
])->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
2021-05-04 18:20:24 +08:00
'message' => trans('skinlib.upload.invalid-size', [
2020-06-04 16:36:10 +08:00
'type' => trans('general.skin'),
'width' => 100,
'height' => 50,
]),
2017-11-24 18:54:30 +08:00
]);
2021-05-04 18:20:24 +08:00
$this->postJson(route('texture.upload'), [
'name' => 'texture',
'public' => true,
'type' => 'cape',
'file' => UploadedFile::fake()->image('texture.png', 100, 50),
])->assertJson([
'code' => 1,
'message' => trans('skinlib.upload.invalid-size', [
'type' => trans('general.cape'),
'width' => 100,
'height' => 50,
]),
]);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'public' => true,
'type' => 'cape',
'file' => UploadedFile::fake()->image('texture.png', 64, 30),
])->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
2020-06-04 16:36:10 +08:00
'message' => trans('skinlib.upload.invalid-size', [
'type' => trans('general.cape'),
'width' => 64,
'height' => 30,
]),
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
2020-06-04 16:36:10 +08:00
// score is not enough
2020-10-14 11:56:34 +08:00
$user = User::factory()->create(['score' => 0]);
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
2020-06-05 23:35:49 +08:00
->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
2020-06-05 23:42:12 +08:00
'public' => '1',
2020-06-04 16:36:10 +08:00
'type' => 'steve',
'file' => $upload,
])
2018-07-13 19:02:16 +08:00
->assertJson([
2020-06-04 16:36:10 +08:00
'code' => 1,
2019-04-23 11:47:45 +08:00
'message' => trans('skinlib.upload.lack-score'),
2018-07-13 19:02:16 +08:00
]);
2020-10-14 11:56:34 +08:00
$user = User::factory()->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(
2020-06-05 23:35:49 +08:00
route('texture.upload'),
2018-07-13 19:02:16 +08:00
[
'name' => 'texture',
2020-06-04 16:36:10 +08:00
'public' => false,
2018-07-13 19:02:16 +08:00
'type' => 'steve',
'file' => $upload,
2018-07-13 19:02:16 +08:00
]
)->assertJson([
2020-06-04 16:36:10 +08:00
'code' => 1,
2019-04-23 11:47:45 +08:00
'message' => trans('skinlib.upload.lack-score'),
2017-11-24 18:54:30 +08:00
]);
2019-03-20 23:28:04 +08:00
2020-06-04 16:36:10 +08:00
// success
2019-03-20 23:28:04 +08:00
option(['score_award_per_texture' => 2]);
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'public' => true,
'type' => 'steve',
'file' => $upload,
])->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.upload.success', ['name' => 'texture']),
2017-11-24 18:54:30 +08:00
]);
2020-06-04 16:36:10 +08:00
$texture = Texture::where('name', 'texture')->first();
$disk->assertExists($texture->hash);
$user->refresh();
2019-03-20 23:28:04 +08:00
$this->assertEquals(2, $user->score);
2020-06-04 16:36:10 +08:00
$this->assertEquals('texture', $texture->name);
$this->assertEquals('steve', $texture->type);
$this->assertEquals(1, $texture->likes);
$this->assertEquals(1, $texture->size);
$this->assertEquals($user->uid, $texture->uploader);
$this->assertTrue($texture->public);
$filter->assertApplied('uploaded_texture_file', function ($file) {
$this->assertInstanceOf(UploadedFile::class, $file);
return true;
});
$filter->assertApplied('uploaded_texture_name', function ($name) {
$this->assertEquals('texture', $name);
return true;
});
$filter->assertApplied(
'uploaded_texture_hash',
function ($hash, $file) use ($texture) {
$this->assertEquals($texture->hash, $hash);
$this->assertInstanceOf(Image::class, $file);
2020-06-04 16:36:10 +08:00
return true;
}
);
Event::assertDispatched(
'texture.uploading',
function ($eventName, $payload) use ($texture) {
$this->assertInstanceOf(Image::class, $payload[0]);
2020-06-04 16:36:10 +08:00
$this->assertEquals($texture->name, $payload[1]);
$this->assertEquals($texture->hash, $payload[2]);
return true;
}
);
Event::assertDispatched(
'texture.uploaded',
function ($eventName, $payload) use ($texture) {
$this->assertTrue($texture->is($payload[0]));
$this->assertInstanceOf(Image::class, $payload[1]);
2020-06-04 16:36:10 +08:00
return true;
}
);
// upload a duplicated texture
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
2020-06-05 23:35:49 +08:00
->postJson(route('texture.upload'), [
2020-06-04 16:36:10 +08:00
'name' => 'texture',
'public' => true,
'type' => 'steve',
'file' => $upload,
])->assertJson([
'code' => 2,
2019-04-23 11:47:45 +08:00
'message' => trans('skinlib.upload.repeated'),
2020-06-04 16:36:10 +08:00
'data' => ['tid' => $texture->tid],
2018-07-13 19:02:16 +08:00
]);
// upload a duplicated private texture
$texture->uploader = $user->uid;
$texture->save();
$this->postJson(route('texture.upload'), [
2025-06-26 21:16:56 +08:00
'name' => 'texture',
'public' => true,
'type' => 'steve',
'file' => $upload,
])->assertJson([
'code' => 2,
'message' => trans('skinlib.upload.repeated'),
'data' => ['tid' => $texture->tid],
]);
2020-06-04 16:36:10 +08:00
// rejected
$filter->add('can_upload_texture', function ($can, $file, $name) {
$this->assertInstanceOf(UploadedFile::class, $file);
$this->assertEquals('texture', $name);
return new Rejection('rejected');
});
2020-06-05 23:35:49 +08:00
$this->postJson(route('texture.upload'), [
2025-06-26 21:16:56 +08:00
'name' => 'texture',
'public' => true,
'type' => 'steve',
'file' => $upload,
])->assertJson(['code' => 1, 'message' => 'rejected']);
2020-06-04 16:36:10 +08:00
$disk->delete($texture->hash);
2017-11-24 18:54:30 +08:00
}
public function testDelete()
{
Event::fake();
2020-06-05 23:35:49 +08:00
/** @var FilesystemAdapter */
$disk = Storage::fake('textures');
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
2020-10-14 11:56:34 +08:00
$duplicate = Texture::factory()->create([
2020-06-05 23:35:49 +08:00
'hash' => $texture->hash,
'uploader' => $uploader->uid,
]);
$disk->put($texture->hash, '');
2017-11-24 18:54:30 +08:00
2020-06-05 23:35:49 +08:00
// when file is occupied, the file should not be deleted
$this->actingAs($uploader)
->deleteJson(route('texture.delete', ['texture' => $duplicate]))
2018-07-13 19:02:16 +08:00
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.delete.success'),
2017-11-24 18:54:30 +08:00
]);
2020-06-05 23:35:49 +08:00
$this->assertNull(Texture::find($duplicate->tid));
$disk->assertExists($texture->hash);
Event::assertDispatched(
'texture.deleting',
function ($eventName, $payload) use ($duplicate) {
$this->assertTrue($duplicate->is($payload[0]));
2017-11-24 18:54:30 +08:00
return true;
}
);
Event::assertDispatched(
'texture.deleted',
function ($eventName, $payload) use ($duplicate) {
$this->assertTrue($duplicate->is($payload[0]));
2017-11-24 18:54:30 +08:00
return true;
}
2017-11-24 18:54:30 +08:00
);
// rejected
$filter = Fakes\Filter::fake();
$filter->add('can_delete_texture', function ($can, $t) use ($texture) {
$this->assertTrue($texture->is($t));
return new Rejection('rejected');
});
$this->deleteJson(route('texture.delete', ['texture' => $texture]))
->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->remove('can_delete_texture');
$this->deleteJson(route('texture.delete', ['texture' => $texture]))
2018-07-13 19:02:16 +08:00
->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));
$disk->assertMissing($texture->hash);
2017-11-24 18:54:30 +08:00
}
public function testPrivacy()
{
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$other = User::factory()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
2020-06-05 23:35:49 +08:00
// setting a texture to be private needs more scores
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
$uploader->score = 0;
$uploader->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2020-06-05 23:35:49 +08:00
->putJson(route('texture.privacy', ['texture' => $texture]))
2018-07-13 19:02:16 +08:00
->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
]);
2020-06-05 23:35:49 +08:00
$this->assertTrue($texture->fresh()->public);
2017-11-24 18:54:30 +08:00
// rejected
$filter = Fakes\Filter::fake();
$filter->add('can_update_texture_privacy', function ($can, $t) use ($texture) {
$this->assertTrue($texture->fresh()->is($t));
return new Rejection('rejected');
});
$this->actingAs($uploader)
->putJson(route('texture.privacy', ['texture' => $texture]))
->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->remove('can_update_texture_privacy');
2017-11-24 18:54:30 +08:00
$texture->public = true;
$texture->save();
$uploader->score = $texture->size *
(option('private_score_per_storage') - option('score_per_storage'));
$uploader->save();
$replicated = $texture->replicate();
2020-06-05 23:35:49 +08:00
$this->putJson(route('texture.privacy', ['texture' => $texture]))
2018-07-13 19:02:16 +08:00
->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
]);
2020-06-05 23:35:49 +08:00
$this->assertEquals(0, $uploader->fresh()->score);
$this->assertFalse($texture->fresh()->public);
Event::assertDispatched(
'texture.privacy.updating',
function ($eventName, $payload) use ($replicated) {
$this->assertInstanceOf(Texture::class, $payload[0]);
$this->assertTrue($replicated->public);
return true;
}
);
Event::assertDispatched(
'texture.privacy.updated',
function ($eventName, $payload) {
$this->assertFalse($payload[0]->public);
return true;
}
);
2017-11-24 18:54:30 +08:00
// duplicated
$duplicated = $texture->replicate();
$duplicated->uploader = $other->uid;
$duplicated->public = true;
$duplicated->save();
$texture->public = false;
$texture->save();
$uploader->score = (int) option('private_score_per_storage');
$uploader->save();
$this->putJson(route('texture.privacy', ['texture' => $texture]))
->assertJson(['code' => 2, 'message' => trans('skinlib.upload.repeated')]);
$duplicated->delete();
2020-06-07 10:25:09 +08:00
$this->putJson(route('texture.privacy', ['texture' => $texture]))
->assertJson([
'code' => 0,
'message' => trans('skinlib.privacy.success', ['privacy' => trans('general.public')]),
]);
$this->assertTrue($texture->fresh()->public);
2017-11-24 18:54:30 +08:00
// When setting a texture to be private,
// other players should not be able to use it.
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
$uploader->score += $texture->size * option('private_score_per_storage');
$uploader->save();
2020-06-05 23:35:49 +08:00
$this->putJson(route('texture.privacy', ['texture' => $texture]))
2018-07-13 19:02:16 +08:00
->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
]);
2019-03-14 23:55:49 +08:00
2020-06-05 23:35:49 +08:00
// take back the score
2019-03-20 23:28:04 +08:00
option(['score_award_per_texture' => 5]);
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-03-20 23:28:04 +08:00
$uploader->score = $texture->size * (
option('private_score_per_storage') - option('score_per_storage')
);
$uploader->score += option('score_award_per_texture');
$uploader->save();
2020-06-05 23:35:49 +08:00
$this->putJson(route('texture.privacy', ['texture' => $texture]))
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
2020-06-05 23:35:49 +08:00
$this->assertEquals(0, $uploader->fresh()->score);
2019-03-20 23:28:04 +08:00
2020-06-05 23:35:49 +08:00
// without returning score
2019-03-16 09:56:31 +08:00
option(['return_score' => false, 'private_score_per_storage' => 0]);
$uploader->score += 1000;
$uploader->save();
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->private()->create(['uploader' => $uploader->uid]);
$other = User::factory()->create();
2019-03-14 23:55:49 +08:00
$other->closet()->attach($texture->tid, ['item_name' => 'a']);
2020-06-05 23:35:49 +08:00
$this->putJson(route('texture.privacy', ['texture' => $texture]))
2019-04-23 19:14:41 +08:00
->assertJson(['code' => 0]);
2020-06-05 23:35:49 +08:00
$this->assertEquals($other->score, $other->fresh()->score);
2017-11-24 18:54:30 +08:00
}
public function testRename()
{
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2017-11-24 18:54:30 +08:00
2020-06-05 23:35:49 +08:00
// without `name` field
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2020-06-05 23:35:49 +08:00
->putJson(route('texture.name', ['texture' => $texture]))
->assertJsonValidationErrors('name');
2017-11-24 18:54:30 +08:00
2020-06-05 23:35:49 +08:00
// specified regular expression for texture name
option(['texture_name_regexp' => '/\\d+/']);
$this->putJson(
route('texture.name', ['texture' => $texture]),
['name' => 'abc']
)->assertJsonValidationErrors('name');
option(['texture_name_regexp' => null]);
2017-11-24 18:54:30 +08:00
2020-06-05 23:35:49 +08:00
// success
$this->putJson(
route('texture.name', ['texture' => $texture]),
['name' => 'abc']
)->assertJson([
'code' => 0,
'message' => trans('skinlib.rename.success', ['name' => 'abc']),
]);
$this->assertEquals('abc', $texture->fresh()->name);
Event::assertDispatched(
'texture.name.updating',
function ($eventName, $payload) use ($texture) {
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals('abc', $payload[1]);
return true;
}
);
Event::assertDispatched(
'texture.name.updated',
function ($eventName, $payload) use ($texture) {
$this->assertTrue($texture->fresh()->is($payload[0]));
$this->assertEquals($texture->name, $payload[1]->name);
return true;
}
);
// rejected
$filter = Fakes\Filter::fake();
$filter->add('can_update_texture_name', function ($can, $t, $name) use ($texture) {
$this->assertTrue($texture->is($t));
$this->assertEquals('abc', $name);
return new Rejection('rejected');
});
$this->putJson(
route('texture.name', ['texture' => $texture]),
['name' => 'abc']
)->assertJson(['code' => 1, 'message' => 'rejected']);
2017-11-24 18:54:30 +08:00
}
2020-06-05 23:35:49 +08:00
public function testType()
{
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$other = User::factory()->create();
$texture = Texture::factory()
->alex()
->create(['uploader' => $uploader->uid]);
2020-06-05 23:35:49 +08:00
// missing `type` field
2019-04-04 09:50:48 +08:00
$this->actingAs($uploader)
2020-06-05 23:35:49 +08:00
->putJson(route('texture.type', ['texture' => $texture]))
->assertJsonValidationErrors('type');
2020-06-05 23:35:49 +08:00
// invalid type
$this->putJson(
route('texture.type', ['texture' => $texture]),
['type' => 'nope']
)->assertJsonValidationErrors('type');
2020-06-05 23:35:49 +08:00
// success
$this->putJson(
route('texture.type', ['texture' => $texture]),
['type' => 'steve']
)->assertJson([
'code' => 0,
'message' => trans('skinlib.model.success', ['model' => 'steve']),
]);
$this->assertEquals('steve', $texture->fresh()->type);
Event::assertDispatched(
'texture.type.updating',
function ($eventName, $payload) use ($texture) {
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals('steve', $payload[1]);
return true;
}
);
Event::assertDispatched(
'texture.type.updated',
function ($eventName, $payload) use ($texture) {
$this->assertTrue($texture->fresh()->is($payload[0]));
$this->assertEquals('alex', $payload[1]->type);
return true;
}
);
2020-10-14 11:56:34 +08:00
$duplicate = Texture::factory()->alex()->create([
'uploader' => $other->uid,
'hash' => $texture->hash,
]);
2020-06-05 23:35:49 +08:00
// allow private texture
$duplicate->public = false;
$duplicate->save();
2020-06-05 23:35:49 +08:00
$this->putJson(
route('texture.type', ['texture' => $texture]),
['type' => 'alex']
)->assertJson([
'code' => 0,
'message' => trans('skinlib.model.success', ['model' => 'alex']),
]);
// rejected
$filter = Fakes\Filter::fake();
$filter->add('can_update_texture_type', function ($can, $t, $type) use ($texture) {
$this->assertTrue($texture->is($t));
$this->assertEquals('steve', $type);
return new Rejection('rejected');
});
$this->putJson(
route('texture.type', ['texture' => $texture]),
['type' => 'steve']
)->assertJson(['code' => 1, 'message' => 'rejected']);
}
2017-11-24 18:54:30 +08:00
}