1
1
"""Test Applications API"""
2
2
3
+ import io
3
4
from json import loads
4
5
5
6
from django .core .files .base import ContentFile
7
+ from django .core .files .uploadedfile import InMemoryUploadedFile
6
8
from django .test .client import BOUNDARY , MULTIPART_CONTENT , encode_multipart
7
9
from django .urls import reverse
8
- from rest_framework .test import APITestCase
10
+ from PIL import Image
11
+ from rest_framework .test import APITransactionTestCase
9
12
10
13
from authentik .core .models import Application
11
14
from authentik .core .tests .utils import create_test_admin_user , create_test_flow
17
20
from authentik .providers .saml .models import SAMLProvider
18
21
19
22
20
- class TestApplicationsAPI (APITestCase ):
23
+ class TestApplicationsAPI (APITransactionTestCase ):
21
24
"""Test applications API"""
22
25
23
26
def setUp (self ) -> None :
@@ -40,6 +43,30 @@ def setUp(self) -> None:
40
43
policy = DummyPolicy .objects .create (name = "deny" , result = False , wait_min = 1 , wait_max = 2 ),
41
44
order = 0 ,
42
45
)
46
+ self .test_files = []
47
+
48
+ def tearDown (self ) -> None :
49
+ # Clean up any test files
50
+ for app in [self .allowed , self .denied ]:
51
+ if app .meta_icon :
52
+ app .meta_icon .delete ()
53
+ super ().tearDown ()
54
+
55
+ def create_test_image (self , name = "test.png" ) -> ContentFile :
56
+ """Create a valid test PNG image file.
57
+
58
+ Args:
59
+ name: The name to give the test file
60
+
61
+ Returns:
62
+ ContentFile: A ContentFile containing a valid PNG image
63
+ """
64
+ # Create a small test image
65
+ image = Image .new ("RGB" , (1 , 1 ), color = "red" )
66
+ img_io = io .BytesIO ()
67
+ image .save (img_io , format = "PNG" )
68
+ img_io .seek (0 )
69
+ return ContentFile (img_io .getvalue (), name = name )
43
70
44
71
def test_formatted_launch_url (self ):
45
72
"""Test formatted launch URL"""
@@ -58,19 +85,34 @@ def test_formatted_launch_url(self):
58
85
)
59
86
60
87
def test_set_icon (self ):
61
- """Test set_icon"""
62
- file = ContentFile (b"text" , "name" )
88
+ """Test set_icon and cleanup"""
89
+ # Create a test image file with a simple name
90
+ image = Image .new ("RGB" , (1 , 1 ), color = "red" )
91
+ img_io = io .BytesIO ()
92
+ image .save (img_io , format = "PNG" )
93
+ img_io .seek (0 )
94
+ file = InMemoryUploadedFile (
95
+ img_io ,
96
+ "file" ,
97
+ "test_icon.png" ,
98
+ "image/png" ,
99
+ len (img_io .getvalue ()),
100
+ None ,
101
+ )
63
102
self .client .force_login (self .user )
103
+
104
+ # Test setting icon
64
105
response = self .client .post (
65
106
reverse (
66
107
"authentik_api:application-set-icon" ,
67
108
kwargs = {"slug" : self .allowed .slug },
68
109
),
69
- data = encode_multipart (data = {"file" : file }, boundary = BOUNDARY ),
110
+ data = encode_multipart (BOUNDARY , {"file" : file }),
70
111
content_type = MULTIPART_CONTENT ,
71
112
)
72
113
self .assertEqual (response .status_code , 200 )
73
114
115
+ # Verify icon was set correctly
74
116
app_raw = self .client .get (
75
117
reverse (
76
118
"authentik_api:application-detail" ,
@@ -80,7 +122,36 @@ def test_set_icon(self):
80
122
app = loads (app_raw .content )
81
123
self .allowed .refresh_from_db ()
82
124
self .assertEqual (self .allowed .get_meta_icon , app ["meta_icon" ])
83
- self .assertEqual (self .allowed .meta_icon .read (), b"text" )
125
+ file .seek (0 )
126
+ self .assertEqual (self .allowed .meta_icon .read (), file .read ())
127
+
128
+ # Test icon replacement
129
+ new_image = Image .new ("RGB" , (1 , 1 ), color = "blue" )
130
+ new_img_io = io .BytesIO ()
131
+ new_image .save (new_img_io , format = "PNG" )
132
+ new_img_io .seek (0 )
133
+ new_file = InMemoryUploadedFile (
134
+ new_img_io ,
135
+ "file" ,
136
+ "new_icon.png" ,
137
+ "image/png" ,
138
+ len (new_img_io .getvalue ()),
139
+ None ,
140
+ )
141
+ response = self .client .post (
142
+ reverse (
143
+ "authentik_api:application-set-icon" ,
144
+ kwargs = {"slug" : self .allowed .slug },
145
+ ),
146
+ data = encode_multipart (BOUNDARY , {"file" : new_file }),
147
+ content_type = MULTIPART_CONTENT ,
148
+ )
149
+ self .assertEqual (response .status_code , 200 )
150
+
151
+ # Verify new icon was set and old one was cleaned up
152
+ self .allowed .refresh_from_db ()
153
+ new_file .seek (0 )
154
+ self .assertEqual (self .allowed .meta_icon .read (), new_file .read ())
84
155
85
156
def test_check_access (self ):
86
157
"""Test check_access operation"""
0 commit comments