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

471 lines
16 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Tests;
use App\Models\Report;
use App\Models\Texture;
2019-12-14 11:10:37 +08:00
use App\Models\User;
use Blessing\Filter;
use Blessing\Rejection;
2019-03-30 12:53:40 +08:00
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
class ReportControllerTest extends TestCase
{
2019-03-30 12:53:40 +08:00
use DatabaseTransactions;
public function testSubmit()
{
2019-11-20 15:01:09 +08:00
Event::fake();
$filter = resolve(Filter::class);
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
$texture = Texture::factory()->create();
// without `tid` field
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
->postJson('/skinlib/report')
->assertJsonValidationErrors('tid');
// invalid texture
$this->postJson('/skinlib/report', ['tid' => $texture->tid - 1])
->assertJsonValidationErrors('tid');
// without `reason` field
$this->postJson('/skinlib/report', ['tid' => $texture->tid])
->assertJsonValidationErrors('reason');
// lack of score
$user->score = 0;
$user->save();
option(['reporter_score_modification' => -5]);
$this->postJson('/skinlib/report', ['tid' => $texture->tid, 'reason' => 'reason'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.upload.lack-score'),
]);
2019-11-20 15:01:09 +08:00
option(['reporter_score_modification' => 5]);
// rejection
2019-11-20 15:01:09 +08:00
$filter->add(
'user_can_report',
function ($can, $tid, $reason, $reporter) use ($texture, $user) {
$this->assertEquals($texture->tid, $tid);
$this->assertEquals('reason', $reason);
$this->assertEquals($user->uid, $reporter->uid);
return new Rejection('rejected');
}
);
$this->postJson('/skinlib/report', ['tid' => $texture->tid, 'reason' => 'reason'])
->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->remove('user_can_report');
// success
$this->postJson('/skinlib/report', ['tid' => $texture->tid, 'reason' => 'reason'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('skinlib.report.success'),
]);
$user->refresh();
$this->assertEquals(5, $user->score);
$report = Report::where('reporter', $user->uid)->first();
$this->assertEquals($texture->tid, $report->tid);
$this->assertEquals($texture->uploader, $report->uploader);
$this->assertEquals('reason', $report->reason);
$this->assertEquals(Report::PENDING, $report->status);
2019-11-20 15:01:09 +08:00
Event::assertDispatched('report.submitting', function ($event, $payload) use ($texture, $user) {
[$tid, $reason, $reporter] = $payload;
$this->assertEquals($texture->tid, $tid);
$this->assertEquals('reason', $reason);
$this->assertEquals($user->uid, $reporter->uid);
return true;
});
Event::assertDispatched('report.submitted', function ($event, $payload) use ($texture, $user) {
[$report] = $payload;
$this->assertEquals($texture->tid, $report->tid);
$this->assertEquals($texture->uploader, $report->uploader);
$this->assertEquals($user->uid, $report->reporter);
$this->assertEquals('reason', $report->reason);
$this->assertEquals(Report::PENDING, $report->status);
return true;
});
// prevent duplication
$this->postJson('/skinlib/report', ['tid' => $texture->tid, 'reason' => 'reason'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('skinlib.report.duplicate'),
]);
}
public function testTrack()
{
2020-10-14 11:56:34 +08:00
$user = User::factory()->create();
2019-12-14 11:10:37 +08:00
$report = new Report();
$report->tid = 1;
$report->uploader = 0;
$report->reporter = $user->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($user)
2020-01-21 11:07:20 +08:00
->getJson('/user/reports')
->assertSee('test')
->assertSee(trans('front-end.report.status')[0]);
}
public function testManage()
{
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$reporter = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-12-14 11:10:37 +08:00
$report = new Report();
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
2019-04-04 09:50:48 +08:00
$this->actingAs($reporter)
2020-01-13 08:37:57 +08:00
->getJson('/admin/reports/list')
->assertJson(['data' => [$report->toArray()]]);
}
public function testReview()
{
2019-11-20 15:01:09 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$admin = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $admin->uid]);
2019-12-14 11:10:37 +08:00
$report = new Report();
$report->tid = $texture->tid;
$report->uploader = $admin->uid;
$report->reporter = $admin->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
$report->refresh();
// Without `action` field
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id)
->assertJsonValidationErrors('action');
// invalid action
$this->putJson('/admin/reports/'.$report->id, ['action' => 'a'])
->assertJsonValidationErrors('action');
// allow to process again
$this->putJson('/admin/reports/'.$report->id, ['action' => 'reject'])
2019-05-08 12:51:48 +08:00
->assertJson(['code' => 0]);
2019-11-20 15:01:09 +08:00
$id = $report->id;
Event::assertDispatched('report.reviewing', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('reject', $action);
return true;
});
2019-05-19 16:16:16 +08:00
}
public function testReviewReject()
{
2019-11-20 15:01:09 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$reporter = User::factory()->create();
$admin = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-12-14 11:10:37 +08:00
$report = new Report();
2019-05-19 16:16:16 +08:00
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
2019-05-19 16:16:16 +08:00
$report->refresh();
2019-11-20 15:01:09 +08:00
$id = $report->id;
2019-05-19 16:16:16 +08:00
// should not cost score
$score = $reporter->score;
2019-05-19 16:16:16 +08:00
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'reject'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('general.op-success'),
2019-04-23 19:14:41 +08:00
'data' => ['status' => Report::REJECTED],
]);
$report->refresh();
$reporter->refresh();
$this->assertEquals(Report::REJECTED, $report->status);
$this->assertEquals($score, $reporter->score);
2019-11-20 15:01:09 +08:00
Event::assertDispatched('report.reviewing', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('reject', $action);
return true;
});
Event::assertDispatched('report.rejected', function ($event, $payload) use ($id) {
[$report] = $payload;
$this->assertEquals($id, $report->id);
return true;
});
// should cost score
$report->status = Report::PENDING;
$report->save();
option(['reporter_score_modification' => 5]);
$score = $reporter->score;
$this->putJson('/admin/reports/'.$report->id, ['action' => 'reject'])
2019-04-23 11:47:45 +08:00
->assertJson(['code' => 0]);
$reporter->refresh();
$this->assertEquals($score - 5, $reporter->score);
2019-05-19 16:16:16 +08:00
}
public function testReviewDelete()
{
2019-11-20 15:01:09 +08:00
Event::fake();
$disk = Storage::fake('textures');
2019-11-20 15:01:09 +08:00
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$reporter = User::factory()->create();
$admin = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
$disk->put($texture->hash, '');
2019-05-19 16:16:16 +08:00
2019-12-14 11:10:37 +08:00
$report = new Report();
2019-05-19 16:16:16 +08:00
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
$report->refresh();
2019-11-20 15:01:09 +08:00
$id = $report->id;
$tid = $texture->tid;
2019-05-07 15:16:53 +08:00
option([
'reporter_score_modification' => -7,
'return_score' => false,
'take_back_scores_after_deletion' => false,
]);
$score = $reporter->score;
2019-05-19 16:16:16 +08:00
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'delete'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('general.op-success'),
2019-04-23 19:14:41 +08:00
'data' => ['status' => Report::RESOLVED],
]);
$report->refresh();
$reporter->refresh();
$this->assertEquals(Report::RESOLVED, $report->status);
$this->assertNull(Texture::find($texture->tid));
$this->assertEquals($score + 7, $reporter->score);
Storage::assertMissing($texture->hash);
2019-11-20 15:01:09 +08:00
Event::assertDispatched('report.reviewing', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('delete', $action);
return true;
});
Event::assertDispatched('texture.deleting', function ($event, $payload) use ($tid) {
[$texture] = $payload;
$this->assertEquals($tid, $texture->tid);
return true;
});
2019-11-20 15:01:09 +08:00
Event::assertDispatched('texture.deleted', function ($event, $payload) use ($tid) {
[$texture] = $payload;
$this->assertEquals($tid, $texture->tid);
return true;
});
Event::assertDispatched('report.resolved', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('delete', $action);
return true;
});
$texture = Texture::factory()->create();
// no errors should be occurred even reporter doesn't exist
$report = new Report();
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = 0;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
$report->refresh();
$id = $report->id;
$tid = $texture->tid;
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'delete'])
->assertJson([
'code' => 0,
'message' => trans('general.op-success'),
'data' => ['status' => Report::RESOLVED],
]);
2019-05-19 14:44:17 +08:00
}
2019-05-19 16:16:16 +08:00
2019-05-19 17:04:17 +08:00
public function testReviewDeleteNonExistentTexture()
{
2019-11-20 15:01:09 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$reporter = User::factory()->create();
$admin = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-05-19 17:04:17 +08:00
2019-12-14 11:10:37 +08:00
$report = new Report();
2019-05-19 17:04:17 +08:00
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
$report->refresh();
2019-11-20 15:01:09 +08:00
$id = $report->id;
2019-05-19 17:04:17 +08:00
option([
'reporter_reward_score' => 6,
'reporter_score_modification' => -7,
]);
$score = $reporter->score;
$texture->delete();
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'delete'])
2019-05-19 17:04:17 +08:00
->assertJson([
'code' => 0,
'message' => trans('general.texture-deleted'),
'data' => ['status' => Report::RESOLVED],
]);
$report->refresh();
$this->assertEquals(Report::RESOLVED, $report->status);
$this->assertEquals($score, $reporter->score);
2019-11-20 15:01:09 +08:00
Event::assertNotDispatched('texture.deleted');
Event::assertDispatched('report.resolved', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('delete', $action);
return true;
});
2019-05-19 17:04:17 +08:00
}
2019-05-19 16:16:16 +08:00
public function testReviewBan()
2019-05-19 14:44:17 +08:00
{
2019-11-20 15:01:09 +08:00
Event::fake();
2020-10-14 11:56:34 +08:00
$uploader = User::factory()->create();
$reporter = User::factory()->create();
$admin = User::factory()->admin()->create();
$texture = Texture::factory()->create(['uploader' => $uploader->uid]);
2019-12-14 11:10:37 +08:00
$report = new Report();
2019-05-19 14:44:17 +08:00
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
2019-05-19 16:16:16 +08:00
$report->status = Report::PENDING;
2019-05-19 14:44:17 +08:00
$report->save();
$report->refresh();
2019-11-20 15:01:09 +08:00
$id = $report->id;
2019-05-19 16:16:16 +08:00
// uploader should be banned
option(['reporter_reward_score' => 6]);
$score = $reporter->score;
2019-05-19 14:49:49 +08:00
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'ban'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 0,
'message' => trans('general.op-success'),
2019-04-23 19:14:41 +08:00
'data' => ['status' => Report::RESOLVED],
]);
$reporter->refresh();
2019-05-19 14:02:44 +08:00
$uploader->refresh();
$this->assertEquals(User::BANNED, $uploader->permission);
$this->assertEquals($score + 6, $reporter->score);
option(['reporter_reward_score' => 0]);
// should not ban admin uploader
$report->refresh();
$report->status = Report::PENDING;
$report->save();
$uploader->refresh();
$uploader->permission = User::ADMIN;
$uploader->save();
$this->putJson('/admin/reports/'.$report->id, ['action' => 'ban'])
->assertJson([
2019-04-23 11:47:45 +08:00
'code' => 1,
'message' => trans('admin.users.operations.no-permission'),
]);
$report->refresh();
$this->assertEquals(Report::PENDING, $report->status);
2019-05-19 16:16:16 +08:00
$this->assertEquals(User::ADMIN, $uploader->permission);
2019-11-20 15:01:09 +08:00
Event::assertDispatched('report.reviewing', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('ban', $action);
return true;
});
Event::assertDispatched('user.banned', function ($event, $payload) use ($uploader) {
[$up] = $payload;
$this->assertEquals($uploader->uid, $up->uid);
return true;
});
Event::assertDispatched('report.resolved', function ($event, $payload) use ($id) {
[$report, $action] = $payload;
$this->assertEquals($id, $report->id);
$this->assertEquals('ban', $action);
return true;
});
2019-05-19 16:16:16 +08:00
// uploader has deleted its account
2019-05-19 14:44:17 +08:00
$report->uploader = -1;
$report->save();
$this->putJson('/admin/reports/'.$report->id, ['action' => 'ban'])
2019-05-19 14:44:17 +08:00
->assertJson([
'code' => 1,
'message' => trans('admin.users.operations.non-existent'),
2019-05-19 14:44:17 +08:00
]);
$uploader->permission = User::NORMAL;
$uploader->save();
// no errors should be occurred even reporter doesn't exist
$report = new Report();
$report->tid = $texture->tid;
$report->uploader = $uploader->uid;
$report->reporter = $reporter->uid;
$report->reason = 'test';
$report->status = Report::PENDING;
$report->save();
$report->refresh();
$id = $report->id;
$this->actingAs($admin)
->putJson('/admin/reports/'.$report->id, ['action' => 'ban'])
->assertJson([
'code' => 0,
'message' => trans('general.op-success'),
'data' => ['status' => Report::RESOLVED],
]);
}
}