7434635c759e112d08ebcaad012caf42e9b48574
[ipypbx] / src / ipypbx / tests / test_http.py
1 # Copyright (c) Stas Shtin, 2010
2
3 # This file is part of IPyPBX.
4
5 # IPyPBX is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9
10 # IPyPBX is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with IPyPBX.  If not, see <http://www.gnu.org/licenses/>.
17
18 import unittest
19 from ipypbx import http
20 from ipypbx.tests import support
21 from xml.etree import ElementTree as etree
22
23
24 class TestHttpRequestParser(unittest.TestCase):
25     """
26     Tests for ipypbx.http.HttpRequestParser.
27     """    
28     def setUp(self):
29         """
30         Initialize request object.
31         """
32         self.request = http.HttpRequestParser()
33
34     def test_initial_state(self):
35         """
36         Check the default values.
37         """
38         self.assertEqual(self.request.method, None)        
39         self.assertEqual(self.request.request_path, None)        
40         self.assertEqual(self.request.http_version, None)        
41         self.assertEqual(self.request.headers, {})        
42         self.assertEqual(self.request.data, {})        
43         self.assertEqual(self.request.result, None)        
44         self.assertEqual(self.request.state, self.request.HTTP_NONE)
45
46     def test_handle_none(self):
47         """
48         HttpRequestParser.handleNone should just invoke next method and got to
49         headers parsing.
50         """
51         self.request.handle('GET / HTTP/1.1')
52         self.assertNotEqual(self.request.state, self.request.HTTP_NONE)
53
54
55     def test_handle_request(self):
56         """
57         HttpRequestParser.handleRequest should get method, request path and HTTP
58         version from the request and move to headers parsing.
59         """
60         self.request.handle('GET / HTTP/1.1')
61         self.assertEqual(self.request.method, 'GET')
62         self.assertEqual(self.request.request_path, '/')
63         self.assertEqual(self.request.http_version, 'HTTP/1.1')
64         
65         self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
66         
67
68     def test_handle_headers(self):
69         """
70         HttpRequestParser.handleNone should parse headers until empty line is
71         received.
72         """
73         # Move to target state.
74         self.request.handle('GET / HTTP/1.1')
75
76         # Handle first header.
77         self.request.handle('Foo: bar')
78         self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
79         self.assertEqual(self.request.headers['Foo'], 'bar')
80         self.assertEqual(len(self.request.headers), 1)
81
82         # Handle next header.
83         self.request.handle('Qwe: asd')
84         self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
85         self.assertEqual(self.request.headers['Qwe'], 'asd')
86         self.assertEqual(len(self.request.headers), 2)
87
88         # Empty line terminates 
89         self.request.handle('')
90         self.assertNotEqual(self.request.state, self.request.HTTP_HEADERS)
91         self.assertEqual(self.request.headers['Qwe'], 'asd')
92         self.assertEqual(len(self.request.headers), 2)
93         
94     def test_handle_empty(self):
95         """
96         HttpRequestParser.handleEmpty just passes to next state.
97         """
98         prev_state = self.request.state
99         self.request.handleEmpty('')
100         self.assertEqual(self.request.state, prev_state + 1)
101
102     def _run_lines(self, *lines):
103         for line in lines:
104             self.request.handle(line)        
105
106     def test_handle_body(self):
107         """
108         HttpRequestParse.handleBody should parse variables from POST request.
109         """
110         self._run_lines(
111             'POST / HTTP/1.1',
112             '',
113             'foo=bar&qwe=asd')
114         self.assertEqual(self.request.data, {'foo': 'bar', 'qwe': 'asd'})
115         
116     def test_handle_body_with_missing_values(self):
117         """
118         Missing values should give empty results.
119         """
120         self._run_lines(
121             'POST / HTTP/1.1',
122             '',
123             'foo=bar&qwe=')
124         self.assertEqual(self.request.data, {'foo': 'bar', 'qwe': ''})
125                 
126     def test_non_post_fails(self):
127         """
128         We expect only POST requests from Freeswitch, for anything else we
129         get an error.
130         """
131         self.request.handle('GET / HTTP/1.1')
132         self.request.handle('')
133         self.assertRaises(
134             http.HttpParseError, self.request.handle,
135             'Only post requests work')
136
137         
138 class TestFreeswitchConfigGenerator(unittest.TestCase):
139     def setUp(self):
140         self.generator = http.FreeswitchConfigGenerator()
141         
142     def test_can_handle(self):
143         self.generator.param_match = {'foo': 'bar'}
144         self.assertEqual(self.generator.canHandle({'foo': 'bar'}), True)
145         self.assertEqual(self.generator.canHandle({'foo': 'xxx'}), False)
146         self.assertEqual(self.generator.canHandle({'xxx': 'bar'}), False)
147         self.assertEqual(
148             self.generator.canHandle({'foo': 'bar', 'qwe': 'asd'}), True)
149         self.assertEqual(self.generator.canHandle({'qwe': 'asd'}), False)
150
151         self.generator.param_match = {'foo': 'bar', 'baz': '123'}
152         self.assertEqual(self.generator.canHandle({'foo': 'bar'}), False)
153         self.assertEqual(
154             self.generator.canHandle({'foo': 'bar', 'baz': '123'}), True)
155         self.assertEqual(
156             self.generator.canHandle({'foo': 'bar', 'qwe': 'asd'}), False)
157                          
158     def test_base_elements(self):
159         self.generator.param_match = {'section': 'foo'}
160         root_elt, section_elt = self.generator.baseElements
161         self.assertEqual(
162             etree.tostring(root_elt),
163             '<document type="freeswitch/xml"><section name="foo" />'
164             '</document>')
165         self.assertEqual(
166             etree.tostring(section_elt), '<section name="foo" />')
167
168     def test_add_params(self):
169         foo_elt = etree.Element('foo')
170         self.assertEqual(
171             etree.tostring(self.generator.addParams(foo_elt, (('qwe', 'asd'),))),
172             '<foo><params><param name="qwe" value="asd" /></params></foo>')
173
174
175         bar_elt = etree.Element('bar')
176         self.assertEqual(
177             etree.tostring(
178                 self.generator.addParams(bar_elt,
179                                          (('qwe', 'asd'), ('zxc', '123')))),
180             '<bar><params><param name="qwe" value="asd" />'
181             '<param name="zxc" value="123" /></params></bar>')