import unittest
from turbogears import controllers, expose
from turbogears.paginate import paginate
from turbogears import testutil
from turbogears import config
import cherrypy

class MyRoot(controllers.RootController):
    def get_data(self):
        data = []
        for i in range(100):
            data.append(dict(id=i, name='value%d' % i))
        return data

    # This currently doesn't work when tg.strict_parameters == False
    @expose(template='kid:turbogears.tests.test_paginate_template')
    @paginate('data', limit=5)
    def no_args(self):
        return dict(data=self.get_data())

    @expose(template='kid:turbogears.tests.test_paginate_template')
    @paginate('data', limit=5)
    def has_args(self, **kwargs):
        return dict(data=self.get_data())
        
    
class TestPaginate(unittest.TestCase):
    def setUp(self):
        self.old_strict = config.get('tg.strict_parameters')
        config.update({'tg.strict_parameters': False})
        config.update({'tg.include_widgets': []})
        cherrypy.root = None
        cherrypy.tree.mount_points = {}
        cherrypy.tree.mount(MyRoot(), "/")

    def tearDown(self):
        cherrypy.root = None
        cherrypy.tree.mount_points = {}
        config.update({'tg.strict_parameters': self.old_strict})

    def _get_response(self, method, page_number):
        # Get the response for the given method on the given page.
        url = '/%s?tg_paginate_no=%s' % (method, page_number)
        testutil.createRequest(url)
        body = cherrypy.response.body[0]
        return body

    def _test_second_page(self, method):
        # Try and get the second page of output from the given method
        # and check that it really contains values 5 to 9
        body = self._get_response(method, 2)
        print body
        assert "Current page: 2" in body, "Current page is not 2"
        for value in range(5, 10):
            expected = 'ID: %s, name: value%s' % (value, value)
            assert expected in body, "Value %s not in body" % value
        # Check the values either side aren't in the response
        for value in [4, 10]:
            unexpected = 'ID: %s, name: value%s' % (value, value)
            assert unexpected not in body
    
    def test_has_args(self):
        self._test_second_page('has_args')


    def test_no_args(self):
        self._test_second_page('no_args')


    def test_no_args_strict(self):
        # Same as test_no_args but enable strict parameters
        config.update({'tg.strict_parameters': True})
        self.test_no_args()
