183 lines
6.5 KiB
PHP
183 lines
6.5 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(0, PhotoRead::query()->count());
|
|
|
|
$this->actingAs($a, 'admin')
|
|
->get(route('admin.devices.photo', [$device, $photo->id, 'seen' => 1]))
|
|
->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, 'seen' => 1]))
|
|
->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);
|
|
|
|
$tab = $this->actingAs($admin, 'admin')
|
|
->getJson(route('admin.devices.tabData', [$device, 'tab' => 'photos', 'read' => '0']))
|
|
->assertOk()
|
|
->assertJsonPath('count', 1)
|
|
->assertJsonPath('data.0.read', 0);
|
|
|
|
$this->assertStringContainsString('seen=1', (string) $tab->json('data.0.url'));
|
|
}
|
|
|
|
#[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, 'seen' => 1]))
|
|
->assertOk();
|
|
|
|
$list = $this->actingAs($agent, 'agent')
|
|
->getJson(route('user.photos.data'))
|
|
->assertOk()
|
|
->assertJsonPath('data.0.read', 0);
|
|
$this->assertStringNotContainsString('seen=1', (string) $list->json('data.0.url'));
|
|
|
|
$this->actingAs($agent, 'agent')
|
|
->get(route('user.devices.photo', [$device, $photo->id, 'seen' => 1]))
|
|
->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());
|
|
}
|
|
}
|