--- /dev/null
+# Copyright (c) Stas Shtin, 2010
+
+# This file is part of IPyPBX.
+
+# IPyPBX is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# IPyPBX is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with IPyPBX. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+from ipypbx import http
+
+
+class TestHttpRequestParser(unittest.TestCase):
+ """
+ Tests for ipypbx.http.HttpRequestParser.
+ """
+ def setUp(self):
+ """
+ Initialize request object.
+ """
+ self.request = http.HttpRequestParser()
+
+ def test_initial_state(self):
+ """
+ Check the default values.
+ """
+ self.assertEqual(self.request.method, None)
+ self.assertEqual(self.request.request_path, None)
+ self.assertEqual(self.request.http_version, None)
+ self.assertEqual(self.request.headers, {})
+ self.assertEqual(self.request.data, {})
+ self.assertEqual(self.request.result, None)
+ self.assertEqual(self.request.state, self.request.HTTP_NONE)
+
+ def test_handle_none(self):
+ """
+ HttpRequestParser.handleNone should just invoke next method and got to
+ headers parsing.
+ """
+ self.request.handle('GET / HTTP/1.1')
+ self.assertNotEqual(self.request.state, self.request.HTTP_NONE)
+
+
+ def test_handle_request(self):
+ """
+ HttpRequestParser.handleRequest should get method, request path and HTTP
+ version from the request and move to headers parsing.
+ """
+ self.request.handle('GET / HTTP/1.1')
+ self.assertEqual(self.request.method, 'GET')
+ self.assertEqual(self.request.request_path, '/')
+ self.assertEqual(self.request.http_version, 'HTTP/1.1')
+
+ self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
+
+
+ def test_handle_headers(self):
+ """
+ HttpRequestParser.handleNone should parse headers until empty line is
+ received.
+ """
+ # Move to target state.
+ self.request.handle('GET / HTTP/1.1')
+
+ # Handle first header.
+ self.request.handle('Foo: bar')
+ self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
+ self.assertEqual(self.request.headers['Foo'], 'bar')
+ self.assertEqual(len(self.request.headers), 1)
+
+ # Handle next header.
+ self.request.handle('Qwe: asd')
+ self.assertEqual(self.request.state, self.request.HTTP_HEADERS)
+ self.assertEqual(self.request.headers['Qwe'], 'asd')
+ self.assertEqual(len(self.request.headers), 2)
+
+ # Empty line terminates
+ self.request.handle('')
+ self.assertNotEqual(self.request.state, self.request.HTTP_HEADERS)
+ self.assertEqual(self.request.headers['Qwe'], 'asd')
+ self.assertEqual(len(self.request.headers), 2)
+
+ def test_handle_empty(self):
+ """
+ HttpRequestParser.handleEmpty just passes to next state.
+ """
+ prev_state = self.request.state
+ self.request.handleEmpty('')
+ self.assertEqual(self.request.state, prev_state + 1)
+
+ def _run_lines(self, *lines):
+ for line in lines:
+ self.request.handle(line)
+
+ def test_handle_body(self):
+ self._run_lines(
+ 'POST / HTTP/1.1',
+ '',
+ 'foo=bar&qwe=asd')
+ self.assertEqual(self.request.data, {'foo': 'bar', 'qwe': 'asd'})
+
+ def test_handle_body_with_missing_values(self):
+ self._run_lines(
+ 'POST / HTTP/1.1',
+ '',
+ 'foo=bar&qwe=')
+ self.assertEqual(self.request.data, {'foo': 'bar', 'qwe': ''})
+
+
+ def test_non_post_fails(self):
+ self.request.handle('GET / HTTP/1.1')
+ self.request.handle('')
+ self.assertRaises(
+ http.HttpParseError, self.request.handle,
+ 'Only post requests work')
+
+