1+ <?php
2+
3+ namespace Tests \Unit ;
4+
5+ use Tests \TestCase ;
6+ use App \Rules \SecureFileUpload ;
7+ use Illuminate \Http \UploadedFile ;
8+
9+ class SecureFileUploadTest extends TestCase
10+ {
11+ /** @test */
12+ public function test_validasi_pass_untuk_file_valid ()
13+ {
14+ $ rule = new SecureFileUpload (['image/jpeg ' ], 2048 );
15+ $ file = UploadedFile::fake ()->image ('test.jpg ' , 100 , 100 );
16+
17+ $ hasFailed = false ;
18+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ hasFailed ) {
19+ $ hasFailed = true ;
20+ });
21+
22+ $ this ->assertFalse ($ hasFailed , 'File valid seharusnya lolos validasi ' );
23+ }
24+
25+ /** @test */
26+ public function test_tolak_ekstensi_berbahaya_php ()
27+ {
28+ $ rule = new SecureFileUpload ();
29+ $ file = UploadedFile::fake ()->create ('malicious.php ' , 100 );
30+
31+ $ failMessage = null ;
32+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ failMessage ) {
33+ $ failMessage = $ message ;
34+ });
35+
36+ $ this ->assertNotNull ($ failMessage );
37+ $ this ->assertStringContainsString ('forbidden file extension ' , $ failMessage );
38+ }
39+
40+ /** @test */
41+ public function test_tolak_ekstensi_berbahaya_exe ()
42+ {
43+ $ rule = new SecureFileUpload ();
44+ $ file = UploadedFile::fake ()->create ('virus.exe ' , 100 );
45+
46+ $ failMessage = null ;
47+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ failMessage ) {
48+ $ failMessage = $ message ;
49+ });
50+
51+ $ this ->assertStringContainsString ('forbidden file extension ' , $ failMessage );
52+ }
53+
54+ /** @test */
55+ public function test_tolak_mime_type_tidak_sesuai ()
56+ {
57+ $ rule = new SecureFileUpload (['image/jpeg ' ], 2048 );
58+ $ file = UploadedFile::fake ()->create ('document.pdf ' , 100 );
59+
60+ $ failMessage = null ;
61+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ failMessage ) {
62+ $ failMessage = $ message ;
63+ });
64+
65+ $ this ->assertNotNull ($ failMessage );
66+ $ this ->assertStringContainsString ('must be one of ' , $ failMessage );
67+ }
68+
69+ /** @test */
70+ public function test_tolak_file_terlalu_besar ()
71+ {
72+ $ rule = new SecureFileUpload (['image/jpeg ' ], 100 ); // Max 100KB
73+ $ file = UploadedFile::fake ()->create ('large.jpg ' , 500 ); // 500KB
74+
75+ $ failMessage = null ;
76+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ failMessage ) {
77+ $ failMessage = $ message ;
78+ });
79+
80+ $ this ->assertNotNull ($ failMessage );
81+ $ this ->assertStringContainsString ('may not be greater than ' , $ failMessage );
82+ }
83+
84+ /** @test */
85+ public function test_tolak_bukan_uploaded_file ()
86+ {
87+ $ rule = new SecureFileUpload ();
88+
89+ $ failMessage = null ;
90+ $ rule ->validate ('file ' , 'not-a-file ' , function ($ message ) use (&$ failMessage ) {
91+ $ failMessage = $ message ;
92+ });
93+
94+ $ this ->assertStringContainsString ('must be a valid file ' , $ failMessage );
95+ }
96+
97+ /** @test */
98+ public function test_semua_ekstensi_berbahaya_ditolak ()
99+ {
100+ $ dangerousExtensions = ['php ' , 'phtml ' , 'php3 ' , 'php4 ' , 'php5 ' , 'exe ' , 'bat ' , 'sh ' ];
101+ $ rule = new SecureFileUpload ();
102+
103+ foreach ($ dangerousExtensions as $ ext ) {
104+ $ file = UploadedFile::fake ()->create ("malicious. {$ ext }" , 100 );
105+
106+ $ failMessage = null ;
107+ $ rule ->validate ('file ' , $ file , function ($ message ) use (&$ failMessage ) {
108+ $ failMessage = $ message ;
109+ });
110+
111+ $ this ->assertNotNull ($ failMessage , "Extension . {$ ext } should be rejected " );
112+ }
113+ }
114+ }
0 commit comments