summaryrefslogtreecommitdiff
path: root/openid/test/test_accept.py
blob: aa13d875d3d502053962bccb966363aa62de2714 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""Test `openid.yadis.accept` module."""
from __future__ import unicode_literals

import os.path
import unittest

from openid.yadis import accept


def getTestData():
    """Read the test data off of disk

    () -> [(int, six.text_type)]
    """
    filename = os.path.join(os.path.dirname(__file__), 'data', 'accept.txt')
    with open(filename, 'rb') as data_file:
        content = data_file.read().decode('utf-8')
        lines = enumerate(content.splitlines(), start=1)
    return lines


def chunk(lines):
    """Return groups of lines separated by whitespace or comments

    [(int, six.text_type)] -> [[(int, six.text_type)]]
    """
    chunks = []
    chunk = []
    for lineno, line in lines:
        stripped = line.strip()
        if not stripped or stripped[0] == '#':
            if chunk:
                chunks.append(chunk)
                chunk = []
        else:
            chunk.append((lineno, stripped))

    if chunk:
        chunks.append(chunk)

    return chunks


def parseLines(chunk):
    """Take the given chunk of lines and turn it into a test data dictionary

    [(int, six.text_type)] -> {six.text_type:(int, six.text_type)}
    """
    items = {}
    for (lineno, line) in chunk:
        header, data = line.split(':', 1)
        header = header.lower()
        items[header] = (lineno, data.strip())

    return items


def parseAvailable(available_text):
    """Parse an Available: line's data

    six.text_type -> [six.text_type]
    """
    return [s.strip() for s in available_text.split(',')]


def parseExpected(expected_text):
    """Parse an Expected: line's data

    six.text_type -> [(six.text_type, float)]
    """
    expected = []
    if expected_text:
        for chunk in expected_text.split(','):
            chunk = chunk.strip()
            mtype, qstuff = chunk.split(';')
            mtype = mtype.strip()
            assert '/' in mtype
            qstuff = qstuff.strip()
            q, qstr = qstuff.split('=')
            assert q == 'q'
            qval = float(qstr)
            expected.append((mtype, qval))

    return expected


class MatchAcceptTest(unittest.TestCase):

    def runTest(self):
        lines = getTestData()
        chunks = chunk(lines)
        data_sets = [parseLines(line) for line in chunks]
        for data in data_sets:
            lnos = []
            lno, accept_header = data['accept']
            lnos.append(lno)
            lno, avail_data = data['available']
            lnos.append(lno)
            try:
                available = parseAvailable(avail_data)
            except Exception:
                print('On line', lno)
                raise

            lno, exp_data = data['expected']
            lnos.append(lno)
            try:
                expected = parseExpected(exp_data)
            except Exception:
                print('On line', lno)
                raise

            accepted = accept.parseAcceptHeader(accept_header)
            actual = accept.matchTypes(accepted, available)
            self.assertEqual(actual, expected)