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

408 lines
14 KiB
PHP
Raw Permalink Normal View History

2017-11-04 17:18:01 +08:00
<?php
2018-08-17 15:25:08 +08:00
namespace Tests;
2017-11-04 17:18:01 +08:00
use App\Models\Texture;
2019-12-14 11:10:37 +08:00
use App\Models\User;
2020-05-28 18:44:42 +08:00
use Blessing\Rejection;
2017-11-04 17:18:01 +08:00
use Illuminate\Foundation\Testing\DatabaseTransactions;
2020-05-28 18:44:42 +08:00
use Illuminate\Support\Facades\Event;
2017-11-04 17:18:01 +08:00
class ClosetControllerTest extends TestCase
{
use DatabaseTransactions;
public function testIndex()
{
2019-12-21 10:41:38 +08:00
$filter = Fakes\Filter::fake();
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
2019-12-21 10:41:38 +08:00
$this->actingAs($user)->get('/user/closet')->assertViewIs('user.closet');
2019-12-21 10:41:38 +08:00
$filter->assertApplied('grid:user.closet');
2017-11-04 17:18:01 +08:00
}
public function testGetClosetData()
{
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
$textures = Texture::factory()->count(10)->create();
$textures->each(function ($t) use ($user) {
$user->closet()->attach($t->tid, ['item_name' => $t->name]);
2017-11-04 17:18:01 +08:00
});
// Use default query parameters
$this->actingAs($user)
->getJson('/user/closet/list')
2018-07-13 15:51:17 +08:00
->assertJsonStructure([
2020-03-20 19:03:10 +08:00
'data' => [['tid', 'name', 'type']],
2017-11-04 17:18:01 +08:00
]);
// Get capes
2020-10-14 11:56:34 +08:00
$cape = Texture::factory()->cape()->create();
$user->closet()->attach($cape->tid, ['item_name' => 'custom_name']);
2020-01-13 08:37:57 +08:00
$this->getJson('/user/closet/list?category=cape')
2020-03-20 19:03:10 +08:00
->assertJson(['data' => [[
2025-06-26 21:16:56 +08:00
'tid' => $cape->tid,
'type' => 'cape',
'pivot' => ['item_name' => 'custom_name'],
],
2019-04-23 19:14:41 +08:00
]]);
2017-11-04 17:18:01 +08:00
// Search by keyword
$random = $textures->random();
2020-01-13 08:37:57 +08:00
$this->getJson('/user/closet/list?q='.$random->name)
2020-03-20 19:03:10 +08:00
->assertJson(['data' => [[
2025-06-26 21:16:56 +08:00
'tid' => $random->tid,
'name' => $random->name,
'type' => $random->type,
],
2019-04-23 19:14:41 +08:00
]]);
2017-11-04 17:18:01 +08:00
}
2020-03-24 18:05:46 +08:00
public function testAllIds()
{
2020-10-14 11:56:34 +08:00
$texture = Texture::factory()->create();
$user = User::factory()->create();
2020-03-24 18:05:46 +08:00
$user->closet()->attach($texture->tid, ['item_name' => '']);
$this->actingAs($user)
->getJson(route('user.closet.ids'))
->assertJson([$texture->tid]);
}
2017-11-04 17:18:01 +08:00
public function testAdd()
{
2020-05-28 18:44:42 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
$uploader = User::factory()->create(['score' => 0]);
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-03-14 23:55:49 +08:00
$likes = $texture->likes;
2017-11-04 17:18:01 +08:00
$name = 'my';
option(['score_per_closet_item' => 10]);
2020-05-28 18:44:42 +08:00
// missing `tid` field
$this->actingAs($user)
->postJson(route('user.closet.add'))
2020-05-29 09:09:10 +08:00
->assertJsonValidationErrors('tid');
2017-11-04 17:18:01 +08:00
// `tid` is not a integer
2018-07-13 15:51:17 +08:00
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2019-03-14 00:30:53 +08:00
['tid' => 'string']
)->assertJsonValidationErrors('tid');
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// missing `name` field
2018-07-13 15:51:17 +08:00
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2019-03-14 00:30:53 +08:00
['tid' => 0]
)->assertJsonValidationErrors('name');
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// rejection
$filter = Fakes\Filter::fake();
$filter->add(
'can_add_closet_item',
function ($can, $tid, $itemName) use ($name, $texture) {
$this->assertEquals($name, $itemName);
$this->assertEquals($texture->tid, $tid);
return new Rejection('rejected');
}
);
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2020-05-28 18:44:42 +08:00
['tid' => $texture->tid, 'name' => $name]
)->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->assertApplied(
'add_closet_item_name',
function ($itemName, $tid) use ($name, $texture) {
$this->assertEquals($name, $itemName);
$this->assertEquals($texture->tid, $tid);
return true;
}
);
Event::assertDispatched(
'closet.adding',
function ($eventName, $payload) use ($name, $texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2020-05-28 18:44:42 +08:00
return true;
}
);
Event::assertNotDispatched('closet.added');
2020-06-03 09:14:47 +08:00
$filter->remove('can_add_closet_item');
2020-05-28 18:44:42 +08:00
// the user doesn't have enough score to add a texture
$user->score = 0;
$user->save();
2018-07-13 15:51:17 +08:00
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2017-11-04 17:18:01 +08:00
['tid' => $texture->tid, 'name' => $name]
2018-07-13 15:51:17 +08:00
)->assertJson([
2020-05-28 18:44:42 +08:00
'code' => 1,
2019-04-23 11:47:45 +08:00
'message' => trans('user.closet.add.lack-score'),
2017-11-04 17:18:01 +08:00
]);
2020-05-28 18:44:42 +08:00
// add a not-existed texture
$user->score = 100;
$user->save();
2018-07-13 15:51:17 +08:00
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2017-11-04 17:18:01 +08:00
['tid' => -1, 'name' => 'my']
2018-07-13 15:51:17 +08:00
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('user.closet.add.not-found'),
2017-11-04 17:18:01 +08:00
]);
2020-05-28 18:44:42 +08:00
// texture is private
2019-03-20 23:28:04 +08:00
option(['score_award_per_like' => 5]);
2020-10-14 11:56:34 +08:00
$privateTexture = Texture::factory()->create([
2019-04-28 11:38:38 +08:00
'public' => false,
'uploader' => $uploader->uid + 1,
]);
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2019-04-28 11:38:38 +08:00
['tid' => $privateTexture->tid, 'name' => $name]
)->assertJson([
'code' => 1,
'message' => trans('skinlib.show.private'),
]);
2020-05-28 18:44:42 +08:00
// administrator can add it.
2020-10-14 11:56:34 +08:00
$privateTexture = Texture::factory()->private()->create([
2020-03-14 14:59:52 +08:00
'uploader' => 0,
2017-11-04 17:18:01 +08:00
]);
2020-10-14 11:56:34 +08:00
$this->actingAs(User::factory()->admin()->create())
2020-03-14 14:59:52 +08:00
->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2020-03-14 14:59:52 +08:00
['tid' => $privateTexture->tid, 'name' => $name]
)->assertJson([
'code' => 0,
'message' => trans('user.closet.add.success', ['name' => $name]),
]);
2020-05-28 18:44:42 +08:00
// add a texture successfully
Event::fake();
$this->actingAs($user)
2020-03-14 14:59:52 +08:00
->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2020-03-14 14:59:52 +08:00
['tid' => $texture->tid, 'name' => $name]
)->assertJson([
'code' => 0,
'message' => trans('user.closet.add.success', ['name' => $name]),
]);
2019-03-14 23:55:49 +08:00
$this->assertEquals($likes + 1, Texture::find($texture->tid)->likes);
$user->refresh();
$this->assertEquals(90, $user->score);
$this->assertEquals(1, $user->closet()->count());
2019-03-20 23:28:04 +08:00
$uploader->refresh();
$this->assertEquals(5, $uploader->score);
2020-05-28 18:44:42 +08:00
Event::assertDispatched(
'closet.adding',
function ($eventName, $payload) use ($name, $texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2020-05-28 18:44:42 +08:00
return true;
}
);
Event::assertDispatched(
'closet.added',
function ($eventName, $payload) use ($name, $texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
return true;
}
);
// if the texture is duplicated, should be warned
2018-07-13 15:51:17 +08:00
$this->postJson(
2020-05-29 09:09:10 +08:00
route('user.closet.add'),
2017-11-04 17:18:01 +08:00
['tid' => $texture->tid, 'name' => $name]
2018-07-13 15:51:17 +08:00
)->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('user.closet.add.repeated'),
2017-11-04 17:18:01 +08:00
]);
}
public function testRename()
{
2020-05-28 18:44:42 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
$texture = Texture::factory()->create();
2017-11-04 17:18:01 +08:00
$name = 'new';
2020-05-28 18:44:42 +08:00
// missing `name` field
$this->actingAs($user)
->putJson(route('user.closet.rename', ['tid' => 0]))
2020-05-29 09:09:10 +08:00
->assertJsonValidationErrors('name');
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// rejection
$filter = Fakes\Filter::fake();
$filter->add(
'can_rename_closet_item',
function ($can, $item, $itemName) use ($texture, $name) {
$this->assertTrue($texture->is($item));
$this->assertEquals($name, $itemName);
return new Rejection('rejected');
}
);
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
2020-05-29 09:09:10 +08:00
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
)->assertJson(['code' => 1, 'message' => 'rejected']);
2020-05-28 18:44:42 +08:00
$filter->assertApplied(
'rename_closet_item_name',
function ($itemName, $tid) use ($name, $texture) {
$this->assertEquals($name, $itemName);
$this->assertEquals($texture->tid, $tid);
return true;
}
);
Event::assertDispatched(
'closet.renaming',
function ($eventName, $payload) use ($name, $texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2020-05-28 18:44:42 +08:00
return true;
}
);
Event::assertNotDispatched('closet.renamed');
2020-06-03 09:14:47 +08:00
$filter->remove('can_rename_closet_item');
$user->closet()->detach($texture->tid);
2020-05-28 18:44:42 +08:00
// rename a not-existed texture
2020-05-29 09:09:10 +08:00
$this->putJson(
route('user.closet.rename', ['tid' => -1]),
['name' => $name]
)->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
]);
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// rename a closet item successfully
Event::fake();
$user->closet()->attach($texture->tid, ['item_name' => $texture->name]);
2020-05-29 09:09:10 +08:00
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
)->assertJson([
'code' => 0,
'message' => trans('user.closet.rename.success', ['name' => $name]),
]);
$this->assertEquals(1, $user->closet()->where('item_name', $name)->count());
2020-05-28 18:44:42 +08:00
Event::assertDispatched(
'closet.renaming',
function ($eventName, $payload) use ($name, $texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2020-05-28 18:44:42 +08:00
return true;
}
);
Event::assertDispatched(
'closet.renamed',
2021-01-02 15:51:37 +08:00
function ($eventName, $payload) use ($texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals($texture->name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
2020-05-28 18:44:42 +08:00
return true;
}
);
2017-11-04 17:18:01 +08:00
}
public function testRemove()
{
2020-05-28 18:44:42 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
$uploader = User::factory()->create(['score' => 5]);
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-03-14 23:55:49 +08:00
$likes = $texture->likes;
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// rename a not-existed texture
$this->actingAs($user)
->deleteJson(route('user.closet.remove', ['tid' => -1]))
2019-04-28 11:38:38 +08:00
->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
]);
Event::assertDispatched('closet.removing', function ($eventName, $payload) use ($user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals(-1, $payload[0]);
$this->assertTrue($user->is($payload[1]));
2020-05-28 18:44:42 +08:00
return true;
});
Event::assertNotDispatched('closet.removed');
// rejection
$filter = Fakes\Filter::fake();
$filter->add('can_remove_closet_item', function ($can, $item) use ($texture) {
$this->assertTrue($texture->is($item));
return new Rejection('rejected');
});
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
2020-05-29 09:09:10 +08:00
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
2020-05-28 18:44:42 +08:00
->assertJson(['code' => 1, 'message' => 'rejected']);
$user->closet()->detach($texture->tid);
2020-06-03 09:14:47 +08:00
$filter->remove('can_remove_closet_item');
2017-11-04 17:18:01 +08:00
2020-05-28 18:44:42 +08:00
// should return score if `return_score` is true
Event::fake();
2019-03-20 23:28:04 +08:00
option(['score_award_per_like' => 5]);
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $user->score;
2020-05-29 09:09:10 +08:00
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
2019-04-28 11:38:38 +08:00
->assertJson([
'code' => 0,
'message' => trans('user.closet.remove.success'),
]);
2020-05-28 18:44:42 +08:00
$this->assertEquals($likes - 1, $texture->fresh()->likes);
$this->assertEquals($score + option('score_per_closet_item'), $user->score);
$this->assertEquals(0, $user->closet()->count());
2019-03-20 23:28:04 +08:00
$uploader->refresh();
$this->assertEquals(0, $uploader->score);
2020-05-28 18:44:42 +08:00
Event::assertDispatched(
'closet.removing',
function ($eventName, $payload) use ($texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertEquals($texture->tid, $payload[0]);
$this->assertTrue($user->is($payload[1]));
2020-05-28 18:44:42 +08:00
return true;
}
);
Event::assertDispatched(
'closet.removed',
function ($eventName, $payload) use ($texture, $user) {
2020-05-28 18:44:42 +08:00
$this->assertTrue($texture->is($payload[0]));
$this->assertTrue($user->is($payload[1]));
2020-05-28 18:44:42 +08:00
return true;
}
);
2017-11-04 17:18:01 +08:00
$texture = Texture::find($texture->tid);
2019-03-14 23:55:49 +08:00
$likes = $texture->likes;
2020-05-28 18:44:42 +08:00
// should not return score if `return_score` is false
2017-11-04 17:18:01 +08:00
option(['return_score' => false]);
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $user->score;
2020-05-29 09:09:10 +08:00
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson(['code' => 0]);
$this->assertEquals($likes - 1, Texture::find($texture->tid)->likes);
$this->assertEquals($score, $user->score);
$this->assertEquals(0, $user->closet()->count());
2017-11-04 17:18:01 +08:00
}
}