create(['device_id' => 'dev-origin-1']); $png = $this->tinyPng(); $path = 'c2/photos/'.$device->device_id.'/shot.png'; $photo = Photo::query()->create([ 'device_id' => $device->id, 'sha256' => hash('sha256', $png), 'path' => $path, 'size' => strlen($png), ]); return [$device, $photo, $png]; } private function tinyPng(): string { $tmp = sys_get_temp_dir().'/album_'.uniqid().'.png'; $im = imagecreatetruecolor(4, 4); imagefilledrectangle($im, 0, 0, 3, 3, imagecolorallocate($im, 9, 8, 7)); imagepng($im, $tmp); $png = (string) file_get_contents($tmp); @unlink($tmp); return $png; } #[Test] public function origin_endpoint_requires_token(): void { config(['coruna.photo_origin.token' => 'secret-origin']); [, $photo, $png] = $this->seedMissingPhoto(); Storage::disk('local')->put($photo->path, $png); $this->get(route('hooks.photo-origin', $photo))->assertUnauthorized(); $this->get(route('hooks.photo-origin', $photo).'?token=wrong')->assertUnauthorized(); $this->get(route('hooks.photo-origin', $photo).'?token=secret-origin') ->assertOk() ->assertHeader('X-Photo-Origin', 'local'); } #[Test] public function origin_endpoint_404s_when_file_missing_locally(): void { config(['coruna.photo_origin.token' => 'secret-origin']); [, $photo] = $this->seedMissingPhoto(); $this->withHeaders(['X-Photo-Origin-Token' => 'secret-origin']) ->get(route('hooks.photo-origin', $photo)) ->assertNotFound(); } #[Test] public function viewing_missing_photo_pulls_from_origin_and_writes_through(): void { config([ 'coruna.photo_origin.url' => 'http://old.example', 'coruna.photo_origin.token' => 'secret-origin', ]); [$device, $photo, $png] = $this->seedMissingPhoto(); $admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]); Http::fake([ 'http://old.example/hooks/photo-origin/'.$photo->id => Http::response($png, 200, [ 'Content-Type' => 'image/png', ]), ]); $this->actingAs($admin, 'admin') ->get(route('admin.devices.photo', [$device, $photo->id])) ->assertOk() ->assertHeader('Content-Type', 'image/png'); Storage::disk('local')->assertExists($photo->path); $this->assertSame($png, Storage::disk('local')->get($photo->path)); } #[Test] public function viewing_missing_photo_without_origin_stays_404(): void { config([ 'coruna.photo_origin.url' => '', 'coruna.photo_origin.token' => '', ]); [$device, $photo] = $this->seedMissingPhoto(); $admin = Admin::query()->create(['username' => 'root', 'password' => 'secret12', 'is_super' => 1]); $this->actingAs($admin, 'admin') ->get(route('admin.devices.photo', [$device, $photo->id])) ->assertNotFound(); Storage::disk('local')->assertMissing($photo->path); } }