blob: 033a0e9ae5df006641353981778e6850bb5ffec0 [file] [log] [blame]
"""
Tests for the gocookies code.
"""
import os
import shutil
import tempfile
import unittest
import urllib.request
import pyrfc3339
from juju.client.gocookies import GoCookieJar
# cookie_content holds the JSON contents of a Go-produced
# cookie file (reformatted so it's not all on one line but
# otherwise unchanged).
cookie_content = """
[
{
"CanonicalHost": "bar.com",
"Creation": "2017-11-17T08:53:55.088820092Z",
"Domain": "bar.com",
"Expires": "2345-11-15T18:16:08Z",
"HostOnly": true,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088822562Z",
"Name": "bar",
"Path": "/",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088822562Z",
"Value": "bar-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088814857Z",
"Domain": "x.foo.com",
"Expires": "2345-11-15T18:16:05Z",
"HostOnly": true,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088884015Z",
"Name": "foo",
"Path": "/path",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088814857Z",
"Value": "foo-path-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088814857Z",
"Domain": "foo.com",
"Expires": "2345-11-15T18:16:06Z",
"HostOnly": false,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088919437Z",
"Name": "foo4",
"Path": "/path",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088814857Z",
"Value": "foo4-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088790709Z",
"Domain": "x.foo.com",
"Expires": "2345-11-15T18:16:01Z",
"HostOnly": true,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088884015Z",
"Name": "foo",
"Path": "/",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088790709Z",
"Value": "foo-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088790709Z",
"Domain": "foo.com",
"Expires": "2345-11-15T18:16:02Z",
"HostOnly": false,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088919437Z",
"Name": "foo1",
"Path": "/",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088790709Z",
"Value": "foo1-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088790709Z",
"Domain": "x.foo.com",
"Expires": "2345-11-15T18:16:03Z",
"HostOnly": true,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088850252Z",
"Name": "foo2",
"Path": "/",
"Persistent": true,
"Secure": true,
"Updated": "2017-11-17T08:53:55.088790709Z",
"Value": "foo2-value"
},
{
"CanonicalHost": "x.foo.com",
"Creation": "2017-11-17T08:53:55.088790709Z",
"Domain": "foo.com",
"Expires": "2345-11-15T18:16:04Z",
"HostOnly": false,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088919437Z",
"Name": "foo3",
"Path": "/",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088790709Z",
"Value": "foo3-value"
}
]
"""
# cookie_content_queries holds a set of queries
# that were automatically generated by running
# the queries on the above cookie_content data
# and printing the results.
cookie_content_queries = [
('http://x.foo.com', [
('foo', 'foo-value'),
('foo1', 'foo1-value'),
('foo3', 'foo3-value'),
]),
('https://x.foo.com', [
('foo', 'foo-value'),
('foo1', 'foo1-value'),
('foo2', 'foo2-value'),
('foo3', 'foo3-value'),
]),
('http://arble.foo.com', [
('foo1', 'foo1-value'),
('foo3', 'foo3-value'),
]),
('http://arble.com', [
]),
('http://x.foo.com/path/x', [
('foo', 'foo-path-value'),
('foo4', 'foo4-value'),
('foo', 'foo-value'),
('foo1', 'foo1-value'),
('foo3', 'foo3-value'),
]),
('http://arble.foo.com/path/x', [
('foo4', 'foo4-value'),
('foo1', 'foo1-value'),
('foo3', 'foo3-value'),
]),
('http://foo.com/path/x', [
('foo4', 'foo4-value'),
('foo1', 'foo1-value'),
('foo3', 'foo3-value'),
]),
]
class TestGoCookieJar(unittest.TestCase):
def setUp(self):
self.dir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.dir)
def test_readcookies(self):
jar = self.load_jar(cookie_content)
self.assert_jar_queries(jar, cookie_content_queries)
def test_roundtrip(self):
jar = self.load_jar(cookie_content)
filename2 = os.path.join(self.dir, 'cookies2')
jar.save(filename=filename2)
jar = GoCookieJar()
jar.load(filename=filename2)
self.assert_jar_queries(jar, cookie_content_queries)
def test_expiry_time(self):
content = '''[
{
"CanonicalHost": "bar.com",
"Creation": "2017-11-17T08:53:55.088820092Z",
"Domain": "bar.com",
"Expires": "2345-11-15T18:16:08Z",
"HostOnly": true,
"HttpOnly": false,
"LastAccess": "2017-11-17T08:53:55.088822562Z",
"Name": "bar",
"Path": "/",
"Persistent": true,
"Secure": false,
"Updated": "2017-11-17T08:53:55.088822562Z",
"Value": "bar-value"
}
]'''
jar = self.load_jar(content)
got_expires = tuple(jar)[0].expires
want_expires = int(pyrfc3339.parse('2345-11-15T18:16:08Z').timestamp())
self.assertEqual(got_expires, want_expires)
def load_jar(self, content):
filename = os.path.join(self.dir, 'cookies')
with open(filename, 'x') as f:
f.write(content)
jar = GoCookieJar()
jar.load(filename=filename)
return jar
def assert_jar_queries(self, jar, queries):
'''Assert that all the given queries (see cookie_content_queries)
are satisfied when run on the given cookie jar.
:param jar CookieJar: the cookie jar to query
:param queries: the queries to run.
'''
for url, want_cookies in queries:
req = urllib.request.Request(url)
jar.add_cookie_header(req)
# We can't use SimpleCookie to find out what cookies
# have been presented, because SimpleCookie
# only allows one cookie with a given name,
# so we naively parse the cookies ourselves, which
# is OK because we know we don't have to deal
# with any complex cases.
cookie_header = req.get_header('Cookie')
got_cookies = []
if cookie_header is not None:
got_cookies = [
tuple(part.split('='))
for part in cookie_header.split('; ')
]
got_cookies.sort()
want_cookies = list(want_cookies)
want_cookies.sort()
self.assertEqual(got_cookies, want_cookies, msg='query {}; got {}; want {}'.format(url, got_cookies, want_cookies))