@@ -170,6 +170,19 @@ def test_accept_headers(self):
170
170
)
171
171
self .assertEqual (
172
172
[str (accepted_type ) for accepted_type in request .accepted_types ],
173
+ [
174
+ "text/html" ,
175
+ "application/xhtml+xml" ,
176
+ "text/*" ,
177
+ "application/xml; q=0.9" ,
178
+ "*/*; q=0.8" ,
179
+ ],
180
+ )
181
+ self .assertEqual (
182
+ [
183
+ str (accepted_type )
184
+ for accepted_type in request .accepted_types_by_precedence
185
+ ],
173
186
[
174
187
"text/html" ,
175
188
"application/xhtml+xml" ,
@@ -196,7 +209,10 @@ def test_precedence(self):
196
209
"text/*, text/plain, text/plain;format=flowed, */*"
197
210
)
198
211
self .assertEqual (
199
- [str (accepted_type ) for accepted_type in request .accepted_types ],
212
+ [
213
+ str (accepted_type )
214
+ for accepted_type in request .accepted_types_by_precedence
215
+ ],
200
216
[
201
217
"text/plain; format=flowed" ,
202
218
"text/plain" ,
@@ -261,6 +277,16 @@ def test_accept_header_priority_overlapping_mime(self):
261
277
"text/*; q=0.8" ,
262
278
],
263
279
)
280
+ self .assertEqual (
281
+ [
282
+ str (accepted_type )
283
+ for accepted_type in request .accepted_types_by_precedence
284
+ ],
285
+ [
286
+ "text/html; q=0.8" ,
287
+ "text/*; q=0.8" ,
288
+ ],
289
+ )
264
290
265
291
def test_no_matching_accepted_type (self ):
266
292
request = HttpRequest ()
@@ -289,7 +315,7 @@ def test_accept_with_param(self):
289
315
]:
290
316
self .assertEqual (request .get_preferred_type (media_types ), expected )
291
317
292
- def test_quality (self ):
318
+ def test_quality_for_media_type_rfc7231 (self ):
293
319
"""
294
320
Taken from https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2.
295
321
"""
@@ -314,7 +340,36 @@ def test_quality(self):
314
340
315
341
for media_types , expected in [
316
342
(["text/html" , "text/html; level=1" ], "text/html; level=1" ),
317
- (["text/html; level=2" , "text/html; level=3" ], "text/html; level=2" ),
343
+ (["text/html; level=2" , "text/html; level=3" ], "text/html; level=3" ),
344
+ ]:
345
+ self .assertEqual (request .get_preferred_type (media_types ), expected )
346
+
347
+ def test_quality_for_media_type_rfc9110 (self ):
348
+ """
349
+ Taken from https://www.rfc-editor.org/rfc/rfc9110.html#section-12.5.1-18.
350
+ """
351
+ request = HttpRequest ()
352
+ request .META ["HTTP_ACCEPT" ] = (
353
+ "text/*;q=0.3, text/plain;q=0.7, text/plain;format=flowed, "
354
+ "text/plain;format=fixed;q=0.4, */*;q=0.5"
355
+ )
356
+
357
+ for media_type , quality in [
358
+ ("text/plain;format=flowed" , 1 ),
359
+ ("text/plain" , 0.7 ),
360
+ ("text/html" , 0.3 ),
361
+ ("image/jpeg" , 0.5 ),
362
+ ("text/plain;format=fixed" , 0.4 ),
363
+ ("text/html;level=3" , 0.3 ), # https://www.rfc-editor.org/errata/eid7138
364
+ ]:
365
+ with self .subTest (media_type ):
366
+ accepted_media_type = request .accepted_type (media_type )
367
+ self .assertIsNotNone (accepted_media_type )
368
+ self .assertEqual (accepted_media_type .quality , quality )
369
+
370
+ for media_types , expected in [
371
+ (["text/plain" , "text/plain; format=flowed" ], "text/plain; format=flowed" ),
372
+ (["text/html" , "image/jpeg" ], "image/jpeg" ),
318
373
]:
319
374
self .assertEqual (request .get_preferred_type (media_types ), expected )
320
375
@@ -334,3 +389,20 @@ def test_quality_breaks_specificity(self):
334
389
self .assertEqual (
335
390
request .get_preferred_type (["text/html" , "text/plain" ]), "text/html"
336
391
)
392
+
393
+ def test_quality_over_specificity (self ):
394
+ """
395
+ For media types with the same quality, prefer the more specific type.
396
+ """
397
+ request = HttpRequest ()
398
+ request .META ["HTTP_ACCEPT" ] = "text/*,image/jpeg"
399
+
400
+ self .assertEqual (request .accepted_type ("text/plain" ).quality , 1 )
401
+ self .assertEqual (request .accepted_type ("text/plain" ).specificity , 1 )
402
+
403
+ self .assertEqual (request .accepted_type ("image/jpeg" ).quality , 1 )
404
+ self .assertEqual (request .accepted_type ("image/jpeg" ).specificity , 2 )
405
+
406
+ self .assertEqual (
407
+ request .get_preferred_type (["text/plain" , "image/jpeg" ]), "image/jpeg"
408
+ )
0 commit comments