2 from datetime
import datetime
4 from django
.test
import TestCase
5 from django
.utils
import unittest
6 from django
.utils
.http
import parse_etags
, quote_etag
, parse_http_date
9 FULL_RESPONSE
= 'Test conditional get response'
10 LAST_MODIFIED
= datetime(2007, 10, 21, 23, 21, 47)
11 LAST_MODIFIED_STR
= 'Sun, 21 Oct 2007 23:21:47 GMT'
12 LAST_MODIFIED_NEWER_STR
= 'Mon, 18 Oct 2010 16:56:23 GMT'
13 LAST_MODIFIED_INVALID_STR
= 'Mon, 32 Oct 2010 16:56:23 GMT'
14 EXPIRED_LAST_MODIFIED_STR
= 'Sat, 20 Oct 2007 23:21:47 GMT'
15 ETAG
= 'b4246ffc4f62314ca13147c9d4f76974'
16 EXPIRED_ETAG
= '7fae4cd4b0f81e7d2914700043aa8ed6'
18 class ConditionalGet(TestCase
):
19 urls
= 'regressiontests.conditional_processing.urls'
21 def assertFullResponse(self
, response
, check_last_modified
=True, check_etag
=True):
22 self
.assertEqual(response
.status_code
, 200)
23 self
.assertEqual(response
.content
, FULL_RESPONSE
)
24 if check_last_modified
:
25 self
.assertEqual(response
['Last-Modified'], LAST_MODIFIED_STR
)
27 self
.assertEqual(response
['ETag'], '"%s"' % ETAG
)
29 def assertNotModified(self
, response
):
30 self
.assertEqual(response
.status_code
, 304)
31 self
.assertEqual(response
.content
, '')
33 def testWithoutConditions(self
):
34 response
= self
.client
.get('/condition/')
35 self
.assertFullResponse(response
)
37 def testIfModifiedSince(self
):
38 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
39 response
= self
.client
.get('/condition/')
40 self
.assertNotModified(response
)
41 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_NEWER_STR
42 response
= self
.client
.get('/condition/')
43 self
.assertNotModified(response
)
44 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_INVALID_STR
45 response
= self
.client
.get('/condition/')
46 self
.assertFullResponse(response
)
47 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
48 response
= self
.client
.get('/condition/')
49 self
.assertFullResponse(response
)
51 def testIfNoneMatch(self
):
52 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
53 response
= self
.client
.get('/condition/')
54 self
.assertNotModified(response
)
55 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
56 response
= self
.client
.get('/condition/')
57 self
.assertFullResponse(response
)
59 # Several etags in If-None-Match is a bit exotic but why not?
60 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s", "%s"' % (ETAG
, EXPIRED_ETAG
)
61 response
= self
.client
.get('/condition/')
62 self
.assertNotModified(response
)
64 def testIfMatch(self
):
65 self
.client
.defaults
['HTTP_IF_MATCH'] = '"%s"' % ETAG
66 response
= self
.client
.put('/condition/etag/', {'data': ''})
67 self
.assertEqual(response
.status_code
, 200)
68 self
.client
.defaults
['HTTP_IF_MATCH'] = '"%s"' % EXPIRED_ETAG
69 response
= self
.client
.put('/condition/etag/', {'data': ''})
70 self
.assertEqual(response
.status_code
, 412)
72 def testBothHeaders(self
):
73 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
74 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
75 response
= self
.client
.get('/condition/')
76 self
.assertNotModified(response
)
78 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
79 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
80 response
= self
.client
.get('/condition/')
81 self
.assertFullResponse(response
)
83 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
84 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
85 response
= self
.client
.get('/condition/')
86 self
.assertFullResponse(response
)
88 def testSingleCondition1(self
):
89 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
90 response
= self
.client
.get('/condition/last_modified/')
91 self
.assertNotModified(response
)
92 response
= self
.client
.get('/condition/etag/')
93 self
.assertFullResponse(response
, check_last_modified
=False)
95 def testSingleCondition2(self
):
96 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
97 response
= self
.client
.get('/condition/etag/')
98 self
.assertNotModified(response
)
99 response
= self
.client
.get('/condition/last_modified/')
100 self
.assertFullResponse(response
, check_etag
=False)
102 def testSingleCondition3(self
):
103 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
104 response
= self
.client
.get('/condition/last_modified/')
105 self
.assertFullResponse(response
, check_etag
=False)
107 def testSingleCondition4(self
):
108 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
109 response
= self
.client
.get('/condition/etag/')
110 self
.assertFullResponse(response
, check_last_modified
=False)
112 def testSingleCondition5(self
):
113 self
.client
.defaults
['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
114 response
= self
.client
.get('/condition/last_modified2/')
115 self
.assertNotModified(response
)
116 response
= self
.client
.get('/condition/etag2/')
117 self
.assertFullResponse(response
, check_last_modified
=False)
119 def testSingleCondition6(self
):
120 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
121 response
= self
.client
.get('/condition/etag2/')
122 self
.assertNotModified(response
)
123 response
= self
.client
.get('/condition/last_modified2/')
124 self
.assertFullResponse(response
, check_etag
=False)
126 def testInvalidETag(self
):
127 self
.client
.defaults
['HTTP_IF_NONE_MATCH'] = r
'"\"'
128 response
= self
.client
.get('/condition/etag/')
129 self
.assertFullResponse(response
, check_last_modified
=False)
132 class ETagProcessing(unittest
.TestCase
):
133 def testParsing(self
):
134 etags
= parse_etags(r
'"", "etag", "e\"t\"ag", "e\\tag", W/"weak"')
135 self
.assertEqual(etags
, ['', 'etag', 'e"t"ag', r
'e\tag', 'weak'])
137 def testQuoting(self
):
138 quoted_etag
= quote_etag(r
'e\t"ag')
139 self
.assertEqual(quoted_etag
, r
'"e\\t\"ag"')
142 class HttpDateProcessing(unittest
.TestCase
):
143 def testParsingRfc1123(self
):
144 parsed
= parse_http_date('Sun, 06 Nov 1994 08:49:37 GMT')
145 self
.assertEqual(datetime
.utcfromtimestamp(parsed
),
146 datetime(1994, 11, 06, 8, 49, 37))
148 def testParsingRfc850(self
):
149 parsed
= parse_http_date('Sunday, 06-Nov-94 08:49:37 GMT')
150 self
.assertEqual(datetime
.utcfromtimestamp(parsed
),
151 datetime(1994, 11, 06, 8, 49, 37))
153 def testParsingAsctime(self
):
154 parsed
= parse_http_date('Sun Nov 6 08:49:37 1994')
155 self
.assertEqual(datetime
.utcfromtimestamp(parsed
),
156 datetime(1994, 11, 06, 8, 49, 37))