add more events for ClosetManagementController

This commit is contained in:
Pig Fang 2020-06-07 10:54:26 +08:00
parent de95ea8111
commit 88e3ed7a07
6 changed files with 128 additions and 76 deletions

View File

@ -83,7 +83,7 @@ class ClosetController extends Controller
/** @var User */
$user = Auth::user();
$name = $filter->apply('add_closet_item_name', $name, [$tid]);
$dispatcher->dispatch('closet.adding', [$tid, $name]);
$dispatcher->dispatch('closet.adding', [$tid, $name, $user]);
$can = $filter->apply('can_add_closet_item', true, [$tid, $name]);
if ($can instanceof Rejection) {
@ -115,7 +115,7 @@ class ClosetController extends Controller
$texture->likes++;
$texture->save();
$dispatcher->dispatch('closet.added', [$texture, $name]);
$dispatcher->dispatch('closet.added', [$texture, $name, $user]);
$uploader = User::find($texture->uploader);
if ($uploader && $uploader->uid != $user->uid) {
@ -137,7 +137,7 @@ class ClosetController extends Controller
$user = auth()->user();
$name = $filter->apply('rename_closet_item_name', $name, [$tid]);
$dispatcher->dispatch('closet.renaming', [$tid, $name]);
$dispatcher->dispatch('closet.renaming', [$tid, $name, $user]);
$item = $user->closet()->find($tid);
if (empty($item)) {
@ -152,7 +152,7 @@ class ClosetController extends Controller
$user->closet()->updateExistingPivot($tid, ['item_name' => $name]);
$dispatcher->dispatch('closet.renamed', [$item, $previousName]);
$dispatcher->dispatch('closet.renamed', [$item, $previousName, $user]);
return json(trans('user.closet.rename.success', ['name' => $name]), 0);
}
@ -162,7 +162,7 @@ class ClosetController extends Controller
/** @var User */
$user = auth()->user();
$dispatcher->dispatch('closet.removing', [$tid]);
$dispatcher->dispatch('closet.removing', [$tid, $user]);
$item = $user->closet()->find($tid);
if (empty($item)) {
@ -185,7 +185,7 @@ class ClosetController extends Controller
$texture->likes--;
$texture->save();
$dispatcher->dispatch('closet.removed', [$texture]);
$dispatcher->dispatch('closet.removed', [$texture, $user]);
$uploader = User::find($texture->uploader);
$uploader->score -= option('score_award_per_like', 0);

View File

@ -4,39 +4,44 @@ namespace App\Http\Controllers;
use App\Models\Texture;
use App\Models\User;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Http\Request;
class ClosetManagementController extends Controller
{
public function list($uid)
public function list(User $user)
{
/** @var User */
$user = User::findOrFail($uid);
return $user->closet;
}
public function add(Request $request, $uid)
public function add(Request $request, Dispatcher $dispatcher, User $user)
{
$tid = $request->input('tid');
/** @var Texture */
$texture = Texture::findOrFail($request->input('tid'));
$texture = Texture::findOrFail($tid);
$name = $texture->name;
/** @var User */
$user = User::findOrFail($uid);
$user->closet()->attach($texture->tid, ['item_name' => $texture->name]);
$dispatcher->dispatch('closet.adding', [$tid, $name, $user]);
$user->closet()->attach($texture->tid, ['item_name' => $name]);
$dispatcher->dispatch('closet.added', [$texture, $name, $user]);
return json('', 0, compact('user', 'texture'));
}
public function remove(Request $request, $uid)
public function remove(Request $request, Dispatcher $dispatcher, User $user)
{
/** @var Texture */
$texture = Texture::findOrFail($request->input('tid'));
$tid = $request->input('tid');
$dispatcher->dispatch('closet.removing', [$tid, $user]);
/** @var Texture */
$texture = Texture::findOrFail($tid);
/** @var User */
$user = User::findOrFail($uid);
$user->closet()->detach($texture->tid);
$dispatcher->dispatch('closet.removed', [$texture, $user]);
return json('', 0, compact('user', 'texture'));
}
}

View File

@ -56,9 +56,9 @@ Route::prefix('admin')
});
Route::prefix('closet')->group(function () {
Route::get('{uid}', 'ClosetManagementController@list');
Route::post('{uid}', 'ClosetManagementController@add');
Route::delete('{uid}', 'ClosetManagementController@remove');
Route::get('{user}', 'ClosetManagementController@list');
Route::post('{user}', 'ClosetManagementController@add');
Route::delete('{user}', 'ClosetManagementController@remove');
});
Route::prefix('reports')->group(function () {

View File

@ -157,8 +157,8 @@ Route::prefix('admin')
});
Route::prefix('closet')->group(function () {
Route::post('{uid}', 'ClosetManagementController@add');
Route::delete('{uid}', 'ClosetManagementController@remove');
Route::post('{user}', 'ClosetManagementController@add');
Route::delete('{user}', 'ClosetManagementController@remove');
});
Route::prefix('reports')->group(function () {

View File

@ -12,42 +12,33 @@ class ClosetControllerTest extends TestCase
{
use DatabaseTransactions;
/**
* @var User
*/
private $user;
protected function setUp(): void
{
parent::setUp();
$this->user = factory(User::class)->create();
$this->actingAs($this->user);
}
public function testIndex()
{
$filter = Fakes\Filter::fake();
$user = factory(User::class)->create();
$this->get('/user/closet')->assertViewIs('user.closet');
$this->actingAs($user)->get('/user/closet')->assertViewIs('user.closet');
$filter->assertApplied('grid:user.closet');
}
public function testGetClosetData()
{
$user = factory(User::class)->create();
$textures = factory(Texture::class, 10)->create();
$textures->each(function ($t) {
$this->user->closet()->attach($t->tid, ['item_name' => $t->name]);
$textures->each(function ($t) use ($user) {
$user->closet()->attach($t->tid, ['item_name' => $t->name]);
});
// Use default query parameters
$this->getJson('/user/closet/list')
$this->actingAs($user)
->getJson('/user/closet/list')
->assertJsonStructure([
'data' => [['tid', 'name', 'type']],
]);
// Get capes
$cape = factory(Texture::class)->states('cape')->create();
$this->user->closet()->attach($cape->tid, ['item_name' => 'custom_name']);
$user->closet()->attach($cape->tid, ['item_name' => 'custom_name']);
$this->getJson('/user/closet/list?category=cape')
->assertJson(['data' => [[
'tid' => $cape->tid,
@ -81,6 +72,7 @@ class ClosetControllerTest extends TestCase
public function testAdd()
{
Event::fake();
$user = factory(User::class)->create();
$uploader = factory(User::class)->create(['score' => 0]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$likes = $texture->likes;
@ -88,7 +80,8 @@ class ClosetControllerTest extends TestCase
option(['score_per_closet_item' => 10]);
// missing `tid` field
$this->postJson(route('user.closet.add'))
$this->actingAs($user)
->postJson(route('user.closet.add'))
->assertJsonValidationErrors('tid');
// `tid` is not a integer
@ -129,9 +122,10 @@ class ClosetControllerTest extends TestCase
);
Event::assertDispatched(
'closet.adding',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
@ -140,8 +134,8 @@ class ClosetControllerTest extends TestCase
$filter->remove('can_add_closet_item');
// the user doesn't have enough score to add a texture
$this->user->score = 0;
$this->user->save();
$user->score = 0;
$user->save();
$this->postJson(
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
@ -151,8 +145,8 @@ class ClosetControllerTest extends TestCase
]);
// add a not-existed texture
$this->user->score = 100;
$this->user->save();
$user->score = 100;
$user->save();
$this->postJson(
route('user.closet.add'),
['tid' => -1, 'name' => 'my']
@ -190,7 +184,7 @@ class ClosetControllerTest extends TestCase
// add a texture successfully
Event::fake();
$this->actingAs($this->user)
$this->actingAs($user)
->postJson(
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
@ -199,25 +193,27 @@ class ClosetControllerTest extends TestCase
'message' => trans('user.closet.add.success', ['name' => $name]),
]);
$this->assertEquals($likes + 1, Texture::find($texture->tid)->likes);
$this->user = User::find($this->user->uid);
$this->assertEquals(90, $this->user->score);
$this->assertEquals(1, $this->user->closet()->count());
$user->refresh();
$this->assertEquals(90, $user->score);
$this->assertEquals(1, $user->closet()->count());
$uploader->refresh();
$this->assertEquals(5, $uploader->score);
Event::assertDispatched(
'closet.adding',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
);
Event::assertDispatched(
'closet.added',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
@ -236,11 +232,13 @@ class ClosetControllerTest extends TestCase
public function testRename()
{
Event::fake();
$user = factory(User::class)->create();
$texture = factory(Texture::class)->create();
$name = 'new';
// missing `name` field
$this->putJson(route('user.closet.rename', ['tid' => 0]))
$this->actingAs($user)
->putJson(route('user.closet.rename', ['tid' => 0]))
->assertJsonValidationErrors('name');
// rejection
@ -254,7 +252,7 @@ class ClosetControllerTest extends TestCase
return new Rejection('rejected');
}
);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
@ -270,16 +268,17 @@ class ClosetControllerTest extends TestCase
);
Event::assertDispatched(
'closet.renaming',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
);
Event::assertNotDispatched('closet.renamed');
$filter->remove('can_rename_closet_item');
$this->user->closet()->detach($texture->tid);
$user->closet()->detach($texture->tid);
// rename a not-existed texture
$this->putJson(
@ -292,7 +291,7 @@ class ClosetControllerTest extends TestCase
// rename a closet item successfully
Event::fake();
$this->user->closet()->attach($texture->tid, ['item_name' => $texture->name]);
$user->closet()->attach($texture->tid, ['item_name' => $texture->name]);
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
@ -300,21 +299,23 @@ class ClosetControllerTest extends TestCase
'code' => 0,
'message' => trans('user.closet.rename.success', ['name' => $name]),
]);
$this->assertEquals(1, $this->user->closet()->where('item_name', $name)->count());
$this->assertEquals(1, $user->closet()->where('item_name', $name)->count());
Event::assertDispatched(
'closet.renaming',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
);
Event::assertDispatched(
'closet.renamed',
function ($eventName, $payload) use ($name, $texture) {
function ($eventName, $payload) use ($name, $texture, $user) {
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals($texture->name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
@ -324,18 +325,21 @@ class ClosetControllerTest extends TestCase
public function testRemove()
{
Event::fake();
$user = factory(User::class)->create();
$uploader = factory(User::class)->create(['score' => 5]);
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
$likes = $texture->likes;
// rename a not-existed texture
$this->deleteJson(route('user.closet.remove', ['tid' => -1]))
$this->actingAs($user)
->deleteJson(route('user.closet.remove', ['tid' => -1]))
->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
]);
Event::assertDispatched('closet.removing', function ($eventName, $payload) {
Event::assertDispatched('closet.removing', function ($eventName, $payload) use ($user) {
$this->assertEquals(-1, $payload[0]);
$this->assertTrue($user->is($payload[1]));
return true;
});
@ -348,39 +352,41 @@ class ClosetControllerTest extends TestCase
return new Rejection('rejected');
});
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson(['code' => 1, 'message' => 'rejected']);
$this->user->closet()->detach($texture->tid);
$user->closet()->detach($texture->tid);
$filter->remove('can_remove_closet_item');
// should return score if `return_score` is true
Event::fake();
option(['score_award_per_like' => 5]);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $this->user->score;
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $user->score;
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson([
'code' => 0,
'message' => trans('user.closet.remove.success'),
]);
$this->assertEquals($likes - 1, $texture->fresh()->likes);
$this->assertEquals($score + option('score_per_closet_item'), $this->user->score);
$this->assertEquals(0, $this->user->closet()->count());
$this->assertEquals($score + option('score_per_closet_item'), $user->score);
$this->assertEquals(0, $user->closet()->count());
$uploader->refresh();
$this->assertEquals(0, $uploader->score);
Event::assertDispatched(
'closet.removing',
function ($eventName, $payload) use ($texture) {
function ($eventName, $payload) use ($texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertTrue($user->is($payload[1]));
return true;
}
);
Event::assertDispatched(
'closet.removed',
function ($eventName, $payload) use ($texture) {
function ($eventName, $payload) use ($texture, $user) {
$this->assertTrue($texture->is($payload[0]));
$this->assertTrue($user->is($payload[1]));
return true;
}
@ -390,12 +396,12 @@ class ClosetControllerTest extends TestCase
$likes = $texture->likes;
// should not return score if `return_score` is false
option(['return_score' => false]);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $this->user->score;
$user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $user->score;
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson(['code' => 0]);
$this->assertEquals($likes - 1, Texture::find($texture->tid)->likes);
$this->assertEquals($score, $this->user->score);
$this->assertEquals(0, $this->user->closet()->count());
$this->assertEquals($score, $user->score);
$this->assertEquals(0, $user->closet()->count());
}
}

View File

@ -5,6 +5,7 @@ namespace Tests;
use App\Models\Texture;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event;
class ClosetManagementControllerTest extends TestCase
{
@ -29,6 +30,7 @@ class ClosetManagementControllerTest extends TestCase
public function testAdd()
{
Event::fake();
$user = factory(User::class)->create();
$texture = factory(Texture::class)->create();
@ -43,10 +45,31 @@ class ClosetManagementControllerTest extends TestCase
$item = $user->closet()->first();
$this->assertEquals($texture->tid, $item->tid);
$this->assertEquals($texture->name, $item->pivot->item_name);
Event::assertDispatched(
'closet.adding',
function ($eventName, $payload) use ($texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertEquals($texture->name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
);
Event::assertDispatched(
'closet.added',
function ($eventName, $payload) use ($texture, $user) {
$this->assertTrue($texture->is($payload[0]));
$this->assertEquals($texture->name, $payload[1]);
$this->assertTrue($user->is($payload[2]));
return true;
}
);
}
public function testRemove()
{
Event::fake();
$user = factory(User::class)->create();
$texture = factory(Texture::class)->create();
$user->closet()->attach($texture->tid, ['item_name' => '']);
@ -60,5 +83,23 @@ class ClosetManagementControllerTest extends TestCase
],
]);
$this->assertCount(0, $user->closet);
Event::assertDispatched(
'closet.removing',
function ($eventName, $payload) use ($texture, $user) {
$this->assertEquals($texture->tid, $payload[0]);
$this->assertTrue($user->is($payload[1]));
return true;
}
);
Event::assertDispatched(
'closet.removed',
function ($eventName, $payload) use ($texture, $user) {
$this->assertTrue($texture->is($payload[0]));
$this->assertTrue($user->is($payload[1]));
return true;
}
);
}
}