63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""Offline regression tests for release validation; never connects to production."""
|
|
import importlib.util
|
|
import sys
|
|
import types
|
|
import unittest
|
|
import urllib.error
|
|
from email.message import Message
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
|
|
spec = importlib.util.spec_from_file_location(
|
|
'publish_test_users', Path(__file__).with_name('baota_publish_test_users.py'))
|
|
release = importlib.util.module_from_spec(spec)
|
|
with patch.dict(sys.modules, {
|
|
'pymysql': types.ModuleType('pymysql'),
|
|
'pwd': types.ModuleType('pwd'),
|
|
}):
|
|
spec.loader.exec_module(release)
|
|
|
|
|
|
class CacheHeaderValidationTest(unittest.TestCase):
|
|
def validate(self, cache_values):
|
|
def fake_query(conn, sql, args=()):
|
|
if 'GROUP BY p.gender' in sql:
|
|
return ((1, 50), (2, 50))
|
|
if 'DISTINCT p.avatar_url' in sql:
|
|
return tuple((release.DOMAIN + '/uploads/%d-1.png' % i,) for i in range(10))
|
|
if 'password_hash' in sql:
|
|
return ((100,),)
|
|
self.fail('Unexpected database query')
|
|
|
|
def fake_fetch(path):
|
|
headers = Message()
|
|
if path.startswith('/uploads/'):
|
|
headers['Content-Type'] = 'image/png'
|
|
return 200, headers, b'\x89PNG\r\n\x1a\n'
|
|
if path in ['/admin/', '/app/']:
|
|
headers['Content-Type'] = 'text/html'
|
|
for value in cache_values:
|
|
headers['Cache-Control'] = value
|
|
return 200, headers, b'<!doctype html><html></html>'
|
|
raise urllib.error.HTTPError(path, 401, 'Unauthorized', headers, None)
|
|
|
|
with patch.object(release, 'query', fake_query), patch.object(release, 'fetch', fake_fetch), patch.object(release, 'health'):
|
|
return release.verify(object())
|
|
|
|
def test_accepts_no_store_in_second_cache_header(self):
|
|
result = self.validate(['no-cache', 'no-store, no-cache, must-revalidate'])
|
|
self.assertEqual(result['total'], 100)
|
|
self.assertEqual(result['avatarsHttp200'], 10)
|
|
|
|
def test_accepts_one_combined_header(self):
|
|
self.validate(['no-store, no-cache, must-revalidate'])
|
|
|
|
def test_rejects_missing_no_store(self):
|
|
with self.assertRaises(AssertionError):
|
|
self.validate(['no-cache'])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|