seed(RoleSeeder::class); $this->organisation = Organisation::factory()->create(); $this->user = User::factory()->create(); $this->organisation->users()->attach($this->user, ['role' => 'org_admin']); Storage::fake('public'); } public function test_upload_image_succeeds_with_valid_png(): void { Sanctum::actingAs($this->user); $file = UploadedFile::fake()->image('logo.png', 200, 200); $response = $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'logo', ]); $response->assertOk() ->assertJsonStructure(['data' => ['url']]); $url = $response->json('data.url'); $this->assertStringContainsString('uploads/logo', $url); } public function test_upload_image_rejects_unsupported_mime(): void { Sanctum::actingAs($this->user); $file = UploadedFile::fake()->create('document.pdf', 100, 'application/pdf'); $response = $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'logo', ]); $response->assertStatus(422); } public function test_upload_image_rejects_oversized_file(): void { Sanctum::actingAs($this->user); $file = UploadedFile::fake()->image('large.png')->size(6000); // 6MB > 5MB limit $response = $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'logo', ]); $response->assertStatus(422); } public function test_upload_image_requires_authentication(): void { $file = UploadedFile::fake()->image('logo.png', 200, 200); $response = $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'logo', ]); $response->assertUnauthorized(); } public function test_upload_image_logs_activity(): void { Sanctum::actingAs($this->user); $file = UploadedFile::fake()->image('logo.png', 200, 200); $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'logo', ]); $this->assertDatabaseHas('activity_log', [ 'log_name' => 'upload', 'description' => 'image.uploaded', 'causer_id' => $this->user->id, ]); } public function test_upload_image_requires_valid_purpose(): void { Sanctum::actingAs($this->user); $file = UploadedFile::fake()->image('logo.png', 200, 200); $response = $this->postJson('/api/v1/upload/image', [ 'file' => $file, 'purpose' => 'invalid', ]); $response->assertUnprocessable() ->assertJsonValidationErrors('purpose'); } }