"""
open/DurusWorks/qp/fill/test/utest_form.py

"""
from durus.logger import direct_output
from durus.utils import BytesIO, as_bytes
from qp.fill.form import Form, get_javascript_code
from qp.fill.widget import MultipleSelectWidget, CheckboxWidget, IntWidget
from qp.fill.widget import SubmitWidget, HiddenWidget
from qp.pub.common import clear_publisher, get_fields
from qp.pub.hit import Hit
from qp.pub.publish import DurusPublisher
from sancho.utest import UTest, raises
import sys

class FormTest(UTest):

    def _pre(self):
        direct_output(sys.stdout)
        clear_publisher()

    def _post(self):
        clear_publisher()

    def a(self):
        publisher = DurusPublisher()
        hit = Hit(None, {})
        publisher.process_hit(hit)
        form = Form()
        form.add_submit('a')
        form.add_reset('b')
        form.add_hidden('c')
        form.add_string('d')
        form.add_text('e')
        form.add_checkbox('f')
        form.add_single_select('g', options=[0])
        form.add_multiple_select('h', options=[0])
        form.add_radiobuttons('i', options=[0])
        form.add_float('j')
        form.add_int('k')
        form.render()
        assert not form.is_submitted()

    def b(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="GET", QUERY_STRING='d=1'))
        publisher.process_hit(hit)
        form = Form()
        form.add_submit('a')
        form.add_string('d')
        assert form.is_submitted()
        form.render()
        assert form.get('d') == '1'
        form.clear()
        assert form.get('d') is None

    def c(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="GET", QUERY_STRING='d=1'))
        publisher.process_hit(hit)
        form = Form(method="get")
        form.add_submit('a')
        form.add_string('d')
        assert form.is_submitted()
        form.render()

    def d(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="POST"))
        publisher.process_hit(hit)
        form = Form(id='ok')
        form.add_submit('a')
        form.add_string('d')
        form.set_error('a', 'err')
        assert not form.is_submitted()
        assert 'id="ok"' in form.render()

    def e(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="GET", QUERY_STRING='d=1'))
        publisher.set_hit(hit)
        form = Form(method="get")
        form.add_submit('a')
        form.add_string('d')
        form.has_key('d')
        assert form.get('d') == '1'
        assert form['d'] == '1'
        assert form.is_submitted()
        get_javascript_code()['a'] = 'javascript'
        assert 'javascript' in str(form.render())

    def f(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="GET", QUERY_STRING='d=1'))
        publisher.set_hit(hit)
        form = Form(method="get")
        form.add(MultipleSelectWidget, 'a', options=[range(10)])
        class FakePersistent(object): pass
        a = FakePersistent()
        b = FakePersistent()
        a._p_durus_id = '11111111'
        b._p_durus_id = '22222222'
        FakePersistent.__str__ = lambda x: 'ok'
        FakePersistent._p_format_durus_id = lambda x: x._p_durus_id
        form.add(MultipleSelectWidget, 'b', options = [a, b])
        raises(AssertionError, # because descriptions are not unique.
               form.add, MultipleSelectWidget, 'c', options = [a, b, 1])

    def g(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="GET", QUERY_STRING='d=1'))
        publisher.set_hit(hit)
        form = Form(method="get")
        form.add(MultipleSelectWidget, 'a', options=[range(10)])
        form.add_string('d')
        assert not form.get_widget('a').is_submitted()
        assert form.get_widget('d').is_submitted()
        assert form.is_submitted()
        assert form.get_widget('a').is_submitted()

    def h(self):
        publisher = DurusPublisher()
        hit = Hit(None, dict(REQUEST_METHOD="POST"))
        publisher.set_hit(hit)
        form = Form()
        widget = form.add_widget(SubmitWidget, 'a', value='a')
        assert len(form.widgets) == 1
        assert len(form.submit_widgets) == 0
        assert len(form.hidden_widgets) == 1
        assert form.widgets[0] is widget
        form.add(SubmitWidget, 'b', value='b')
        assert len(form.widgets) == 1
        assert len(form.submit_widgets) == 1
        assert len(form.hidden_widgets) == 1
        form.add(HiddenWidget, 'c', value='c')
        assert len(form.hidden_widgets) == 2
        assert len(form.submit_widgets) == 1
        assert len(form.widgets) == 1

class WidgetTest (UTest):

    def _pre(self):
        self.publisher = DurusPublisher()

    def _post(self):
        self.publisher = None
        clear_publisher()

    def _form(self, input='', **env):
        input = as_bytes(input)
        env.setdefault('CONTENT_LENGTH', len(input))
        env.setdefault('CONTENT_TYPE', 'application/x-www-form-urlencoded')
        hit = Hit(BytesIO(input), env)
        self.publisher.set_hit(hit)
        return Form(method=env.get('REQUEST_METHOD').lower())

class CheckboxWidgetTest (WidgetTest):

    def a(self):
        form = self._form(REQUEST_METHOD="GET", QUERY_STRING='d=yes')
        form.add(CheckboxWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == True
        form = self._form(input='d=yes', REQUEST_METHOD="POST")
        form.add(CheckboxWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == True

    def b(self):
        form = self._form(REQUEST_METHOD="GET", QUERY_STRING='d=1')
        form.add(CheckboxWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == False, form['d']
        form = self._form(input='d=1', REQUEST_METHOD="POST")
        form.add(CheckboxWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == False, form['d']

class IntWidgetTest (WidgetTest):

    def a(self):
        form = self._form(REQUEST_METHOD="GET", QUERY_STRING='d=24')
        form.add(IntWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == 24
        form = self._form(input='d=24', REQUEST_METHOD="POST")
        form.add(IntWidget, 'd')
        assert form.get_widget('d').is_submitted(), get_fields()
        assert form['d'] == 24, get_fields()

    def b(self):
        form = self._form(REQUEST_METHOD="GET", QUERY_STRING='d=')
        form.add(IntWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == None, form['d']
        form = self._form(input='d=', REQUEST_METHOD="POST")
        form.add(IntWidget, 'd')
        assert form.get_widget('d').is_submitted()
        assert form['d'] == None, form['d']

if __name__ == '__main__':
    FormTest()
    CheckboxWidgetTest()
    IntWidgetTest()
