22
33namespace phpMyFAQ \Controller \Api ;
44
5+ use phpMyFAQ \Attachment \AttachmentFactory ;
56use phpMyFAQ \Configuration ;
67use phpMyFAQ \Database \Sqlite3 ;
8+ use phpMyFAQ \Language ;
79use PHPUnit \Framework \Attributes \AllowMockObjectsWithoutExpectations ;
10+ use PHPUnit \Framework \Attributes \CoversClass ;
11+ use PHPUnit \Framework \Attributes \UsesClass ;
12+ use PHPUnit \Framework \Attributes \UsesNamespace ;
813use PHPUnit \Framework \TestCase ;
914use Symfony \Component \HttpFoundation \JsonResponse ;
1015use Symfony \Component \HttpFoundation \Request ;
@@ -26,6 +31,10 @@ public function isApiEnabled(): bool
2631}
2732
2833#[AllowMockObjectsWithoutExpectations]
34+ #[CoversClass(AttachmentController::class)]
35+ #[UsesNamespace('phpMyFAQ ' )]
36+ #[UsesClass(AbstractApiController::class)]
37+ #[UsesClass(PaginatedResponseOptions::class)]
2938class AttachmentControllerTest extends TestCase
3039{
3140 private ?Sqlite3 $ dbHandle = null ;
@@ -41,6 +50,40 @@ protected function setUp(): void
4150 $ this ->dbHandle = new Sqlite3 ();
4251 $ this ->dbHandle ->connect (PMF_TEST_DIR . '/test.db ' , '' , '' );
4352 new Configuration ($ this ->dbHandle );
53+
54+ Language::$ language = 'en ' ;
55+ $ this ->setAttachmentFactoryStorageType (0 );
56+ }
57+
58+ protected function tearDown (): void
59+ {
60+ $ this ->setAttachmentFactoryStorageType (0 );
61+
62+ parent ::tearDown ();
63+ }
64+
65+ private function setAttachmentFactoryStorageType (?int $ storageType ): void
66+ {
67+ $ reflection = new \ReflectionClass (AttachmentFactory::class);
68+ $ property = $ reflection ->getProperty ('storageType ' );
69+ $ property ->setValue (null , $ storageType );
70+ }
71+
72+ private function insertAttachmentFixture (int $ id , int $ recordId ): void
73+ {
74+ $ query = sprintf (
75+ "INSERT INTO faqattachment (id, record_id, record_lang, real_hash, virtual_hash, password_hash, filename, filesize, encrypted, mime_type) VALUES (%d, %d, 'en', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', NULL, 'fixture-%d.txt', 123, 0, 'text/plain') " ,
76+ $ id ,
77+ $ recordId ,
78+ $ id ,
79+ );
80+
81+ $ this ->dbHandle ?->query($ query );
82+ }
83+
84+ private function deleteAttachmentFixture (int $ id ): void
85+ {
86+ $ this ->dbHandle ?->query(sprintf ('DELETE FROM faqattachment WHERE id = %d ' , $ id ));
4487 }
4588
4689 public function testConstructorWithApiEnabled (): void
@@ -255,4 +298,25 @@ public function testListResponseStructure(): void
255298 }
256299 }
257300 }
301+
302+ public function testListReturnsInternalServerErrorWhenAttachmentFactoryThrows (): void
303+ {
304+ $ fixtureId = 990001 ;
305+ $ this ->insertAttachmentFixture ($ fixtureId , 1 );
306+ $ this ->setAttachmentFactoryStorageType (999 );
307+
308+ $ request = new Request ();
309+ $ request ->attributes ->set ('faqId ' , '1 ' );
310+
311+ $ controller = new AttachmentController ();
312+ $ response = $ controller ->list ($ request );
313+ $ payload = json_decode ($ response ->getContent (), true );
314+
315+ $ this ->deleteAttachmentFixture ($ fixtureId );
316+
317+ $ this ->assertSame (Response::HTTP_INTERNAL_SERVER_ERROR , $ response ->getStatusCode ());
318+ $ this ->assertFalse ($ payload ['success ' ]);
319+ $ this ->assertSame ('Failed to fetch attachments ' , $ payload ['error ' ]['message ' ]);
320+ $ this ->assertSame ('ATTACHMENT_ERROR ' , $ payload ['error ' ]['code ' ]);
321+ }
258322}
0 commit comments