Files
coruna-lab/tests/Feature/PhotoReadTest.php
T
2026-09-06 03:55:24 +08:00

175 lines
6.1 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Admin;
use App\Models\Channel;
use App\Models\Device;
use App\Models\Photo;
use App\Models\PhotoRead;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class PhotoReadTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
Storage::fake('local');
}
private function storePng(Device $device, string $name = 'shot.png'): Photo
{
$tmp = sys_get_temp_dir().'/album_'.uniqid().'.png';
$im = imagecreatetruecolor(4, 4);
imagefilledrectangle($im, 0, 0, 3, 3, imagecolorallocate($im, 1, 2, 3));
imagepng($im, $tmp);
$png = (string) file_get_contents($tmp);
@unlink($tmp);
$path = 'c2/photos/'.$device->device_id.'/'.$name;
Storage::disk('local')->put($path, $png);
return Photo::query()->create([
'device_id' => $device->id,
'sha256' => hash('sha256', $png),
'path' => $path,
'size' => strlen($png),
]);
}
#[Test]
public function viewing_photo_marks_read_for_that_admin_only(): void
{
$a = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]);
$b = Admin::query()->create(['username' => 'staff', 'password' => 'secret12', 'is_super' => 0]);
$device = Device::query()->create(['device_id' => 'dev-read-1']);
$photo = $this->storePng($device);
$this->actingAs($a, 'admin')
->get(route('admin.devices.photo', [$device, $photo->id]))
->assertOk();
$this->assertSame(1, PhotoRead::query()->count());
$row = PhotoRead::query()->first();
$this->assertSame('admin', $row->actor_guard);
$this->assertSame($a->id, $row->actor_id);
$this->assertSame($photo->id, $row->photo_id);
$this->actingAs($a, 'admin')
->getJson(route('admin.photos.data'))
->assertOk()
->assertJsonPath('data.0.read', 1);
$this->actingAs($b, 'admin')
->getJson(route('admin.photos.data'))
->assertOk()
->assertJsonPath('data.0.read', 0);
$this->actingAs($a, 'admin')
->get(route('admin.devices.photo', [$device, $photo->id]))
->assertOk();
$this->assertSame(1, PhotoRead::query()->count());
}
#[Test]
public function photos_data_filters_unread(): void
{
$admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]);
$device = Device::query()->create(['device_id' => 'dev-read-2']);
$seen = $this->storePng($device, 'a.png');
$this->storePng($device, 'b.png');
PhotoRead::mark($seen, 'admin', (int) $admin->id);
$this->actingAs($admin, 'admin')
->getJson(route('admin.photos.data', ['read' => '0']))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('data.0.read', 0);
$this->actingAs($admin, 'admin')
->getJson(route('admin.photos.data', ['read' => '1']))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('data.0.id', $seen->id)
->assertJsonPath('data.0.read', 1);
}
#[Test]
public function device_tab_filters_unread(): void
{
$admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]);
$device = Device::query()->create(['device_id' => 'dev-read-3']);
$seen = $this->storePng($device, 'a.png');
$this->storePng($device, 'b.png');
PhotoRead::mark($seen, 'admin', (int) $admin->id);
$this->actingAs($admin, 'admin')
->getJson(route('admin.devices.tabData', [$device, 'tab' => 'photos', 'read' => '0']))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('data.0.read', 0);
}
#[Test]
public function agent_read_is_separate_from_admin(): void
{
$admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]);
$agent = User::query()->create([
'username' => 'photo_agent',
'password' => 'secret12',
'status' => 1,
]);
Channel::query()->create([
'channel_id' => 'cccccccccccccccccccccccccccccccc',
'user_id' => $agent->id,
'status' => 1,
]);
$device = Device::query()->create([
'device_id' => 'dev-read-agent',
'channel_id' => 'cccccccccccccccccccccccccccccccc',
]);
$photo = $this->storePng($device);
$this->actingAs($admin, 'admin')
->get(route('admin.devices.photo', [$device, $photo->id]))
->assertOk();
$this->actingAs($agent, 'agent')
->getJson(route('user.photos.data'))
->assertOk()
->assertJsonPath('data.0.read', 0);
$this->actingAs($agent, 'agent')
->get(route('user.devices.photo', [$device, $photo->id]))
->assertOk();
$this->assertSame(2, PhotoRead::query()->count());
$this->assertTrue(PhotoRead::query()->where('actor_guard', 'agent')->where('actor_id', $agent->id)->exists());
}
#[Test]
public function missing_file_does_not_mark_read(): void
{
Storage::fake('local');
$admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]);
$device = Device::query()->create(['device_id' => 'dev-read-missing']);
$photo = Photo::query()->create([
'device_id' => $device->id,
'sha256' => str_repeat('a', 64),
'path' => 'c2/photos/dev-read-missing/gone.png',
'size' => 1,
]);
$this->actingAs($admin, 'admin')
->get(route('admin.devices.photo', [$device, $photo->id]))
->assertNotFound();
$this->assertSame(0, PhotoRead::query()->count());
}
}