1"""Module to make discovery data test cases available"""
2import urlparse
3import os.path
4
5from openid.yadis.discover import DiscoveryResult, DiscoveryFailure
6from openid.yadis.constants import YADIS_HEADER_NAME
7
8tests_dir = os.path.dirname(__file__)
9data_path = os.path.join(tests_dir, 'data')
10
11testlist = [
12# success,  input_name,          id_name,            result_name
13    (True,  "equiv",             "equiv",            "xrds"),
14    (True,  "header",            "header",           "xrds"),
15    (True,  "lowercase_header",  "lowercase_header", "xrds"),
16    (True,  "xrds",              "xrds",             "xrds"),
17    (True,  "xrds_ctparam",      "xrds_ctparam",     "xrds_ctparam"),
18    (True,  "xrds_ctcase",       "xrds_ctcase",      "xrds_ctcase"),
19    (False, "xrds_html",         "xrds_html",        "xrds_html"),
20    (True,  "redir_equiv",       "equiv",            "xrds"),
21    (True,  "redir_header",      "header",           "xrds"),
22    (True,  "redir_xrds",        "xrds",             "xrds"),
23    (False, "redir_xrds_html",   "xrds_html",        "xrds_html"),
24    (True,  "redir_redir_equiv", "equiv",            "xrds"),
25    (False, "404_server_response", None,             None),
26    (False, "404_with_header",     None,             None),
27    (False, "404_with_meta",       None,             None),
28    (False, "201_server_response", None,             None),
29    (False, "500_server_response", None,             None),
30    ]
31
32def getDataName(*components):
33    sanitized = []
34    for part in components:
35        if part in ['.', '..']:
36            raise ValueError
37        elif part:
38            sanitized.append(part)
39
40    if not sanitized:
41        raise ValueError
42
43    return os.path.join(data_path, *sanitized)
44
45def getExampleXRDS():
46    filename = getDataName('example-xrds.xml')
47    return file(filename).read()
48
49example_xrds = getExampleXRDS()
50default_test_file = getDataName('test1-discover.txt')
51
52discover_tests = {}
53
54def readTests(filename):
55    data = file(filename).read()
56    tests = {}
57    for case in data.split('\f\n'):
58        (name, content) = case.split('\n', 1)
59        tests[name] = content
60    return tests
61
62def getData(filename, name):
63    global discover_tests
64    try:
65        file_tests = discover_tests[filename]
66    except KeyError:
67        file_tests = discover_tests[filename] = readTests(filename)
68    return file_tests[name]
69
70def fillTemplate(test_name, template, base_url, example_xrds):
71    mapping = [
72        ('URL_BASE/', base_url),
73        ('<XRDS Content>', example_xrds),
74        ('YADIS_HEADER', YADIS_HEADER_NAME),
75        ('NAME', test_name),
76        ]
77
78    for k, v in mapping:
79        template = template.replace(k, v)
80
81    return template
82
83def generateSample(test_name, base_url,
84                   example_xrds=example_xrds,
85                   filename=default_test_file):
86    try:
87        template = getData(filename, test_name)
88    except IOError, why:
89        import errno
90        if why[0] == errno.ENOENT:
91            raise KeyError(filename)
92        else:
93            raise
94
95    return fillTemplate(test_name, template, base_url, example_xrds)
96
97def generateResult(base_url, input_name, id_name, result_name, success):
98    input_url = urlparse.urljoin(base_url, input_name)
99
100    # If the name is None then we expect the protocol to fail, which
101    # we represent by None
102    if id_name is None:
103        assert result_name is None
104        return input_url, DiscoveryFailure
105
106    result = generateSample(result_name, base_url)
107    headers, content = result.split('\n\n', 1)
108    header_lines = headers.split('\n')
109    for header_line in header_lines:
110        if header_line.startswith('Content-Type:'):
111            _, ctype = header_line.split(':', 1)
112            ctype = ctype.strip()
113            break
114    else:
115        ctype = None
116
117    id_url = urlparse.urljoin(base_url, id_name)
118
119    result = DiscoveryResult(input_url)
120    result.normalized_uri = id_url
121    if success:
122        result.xrds_uri = urlparse.urljoin(base_url, result_name)
123    result.content_type = ctype
124    result.response_text = content
125    return input_url, result
126