import turbogears
from nose import with_setup
from turbogears import testutil
#from beadgallery.controllers import Root # Importing this here
                                          # causes problems with the forms
					  # module; we'll do it later.
import cherrypy
from beadgallery import model
from beadgallery.model import Item, User, Group

#cherrypy.root = Root()

class BeadgalleryTest(testutil.DBTest):
    model = model

    def setUp(self):
        testutil.DBTest.setUp(self)
	self.setUpItems()
	self.setUpUsers()

	# THEN import the Root controller, because the form definitions
	# depend on the existence of the item table.
        from beadgallery.controllers import Root
        cherrypy.root = Root()

    def tearDown(self):
        """Tests for apps using identity need to stop CP/TG after each
	test to stop the VisitManager thread. See
	http://trac.turbogears.org/turbogears/ticket/1217
	for details.
	"""
	turbogears.startup.stopTurboGears()
        testutil.DBTest.tearDown(self)

    def setUpItems(self):
        # Ensure there are exactly four items and we know what they are.
        Item.clearTable()
        foo_pattern = Item(title="Foo", type='Pattern', \
  	                   description="This item is the foo pattern.", \
  	                   image="")
        foo_gallery = Item(title="Foo", type='Gallery', \
	                   description="This item is the foo gallery. ", \
	                   image="")
        foo_pattern.addRelated(foo_gallery)
        foo_gallery.addRelated(foo_pattern)
        bar_gallery = Item(title="Bar", type='Gallery', \
	                   description="Bar is not related to anything.", \
	                   image="")
        baz_gallery = Item(title="Baz", type='Gallery', 
	                   description="Baz is related to foo.", \
	                   image="")
        baz_gallery.addRelated(foo_gallery)
        foo_gallery.addRelated(bar_gallery)

    def setUpUsers(self):
        # Ensure there is one administrative user.
        User.clearTable()
	Group.clearTable()
        admin_user = User(user_name='test', display_name='test',
    	                  email_address='test@admin', password='password')
        admin_group = Group(group_name='admin', display_name='admin')
    	admin_group.addUser(admin_user)

class TestControllers(BeadgalleryTest):
    def testIndex(self):
        "Test that index controller returns a dictionary." 
	d = testutil.call(cherrypy.root.index, id=1)
	assert isinstance(d, dict)

    def testView(self):
        "Test that view controller returns an item and data." 
	d = testutil.call(cherrypy.root.view, id=1)
	assert d['item'].id == 1
	assert d['item'].title == 'Foo'
	assert d['item'].type == 'Pattern'
	assert d['data'] is not None

    def testAdmin(self):
        "Test that admin is forbidden for anonymous browsers."
        self.failUnlessRaises(turbogears.identity.IdentityFailure,
	               lambda: testutil.call(cherrypy.root.admin))

class TestAdminControllers(BeadgalleryTest):
    def setUp(self):
        BeadgalleryTest.setUp(self)
	testutil.set_identity_user(User.get(1))
    def tearDown(self):
        testutil.set_identity_user(None)
        BeadgalleryTest.tearDown(self)

    def testAdmin(self):
        "Test that admin is permitted for admin users."
        d = testutil.call(cherrypy.root.admin)
	assert d['items'].count() == 4

class TestView(BeadgalleryTest):
    def testIndex(self):
        "Test for correct links on the index page."
	session = testutil.BrowsingSession()
	session.goto("/index")
        assert '<A HREF="/login">' in session.response 
	assert '<A HREF="/gallery">' in session.response
	assert '<A HREF="/patterns">' in session.response
	assert '<A HREF="/admin">' not in session.response      

    def testView(self):
        "Test for appropriate text and links on on a view page."
	session = testutil.BrowsingSession()
	session.goto("/view?id=1")
	assert "Pattern: Foo" in session.response
	assert "/edit?id=1" not in session.response
	assert "/view?id=2" in session.response
	assert "/view?id=3" not in session.response
	assert "/view?id=4" not in session.response

	session.goto("/view?id=4")
	assert "Gallery: Baz" in session.response
	assert "/edit?id=4" not in session.response
	assert "/view?id=1" not in session.response
	assert "/view?id=2" in session.response
	assert "/view?id=3" not in session.response

class TestAdminView(BeadgalleryTest):
    """ Tests of views from the administrator's perspective.
    See
    http://www.thesamet.com/blog/2006/06/02/four-tips-on-identity-testing/"""

    def testIndex(self):
        "Test that the index shows we are logged in as admin."
        session = testutil.BrowsingSession()
        session.goto('/index?user_name=test&password=password&login=Login')
        assert '<A HREF="/login">' not in session.response
        assert '<A HREF="/gallery">' in session.response
        assert '<A HREF="/patterns">' in session.response
        assert '<A HREF="/admin">' in session.response

    def testAdmin(self):
        "Test the main admin page."
        session = testutil.BrowsingSession()
        session.goto('/admin?user_name=test&password=password&login=Login')
        assert '<A HREF="/login">' not in session.response
        assert '/new' in session.response
        for item in Item.select():
            assert ("/edit?id=%s" % item.id) in session.response

    def testView(self):
        "Test the view page shows link to edit when logged in as admin."
        session.goto('/view?id=1&user_name=test&password=password&login=Login')
        assert '<A HREF="/login">' not in session.response
        assert "/edit?id=1" in session.response


