blob: 2f0462b7b6faa96bcbe2be8e5192b0fdcf77b1ad [file] [log] [blame]
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2013 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.org/wiki/TracLicense.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://trac.edgewall.org/log/.
from __future__ import with_statement
from datetime import datetime
import shutil
from StringIO import StringIO
import tempfile
import unittest
import trac.tests.compat
from trac.attachment import Attachment
from trac.core import *
from trac.resource import Resource
from trac.test import EnvironmentStub
from trac.tests.resource import TestResourceChangeListener
from trac.util.datefmt import utc, to_utimestamp
from trac.wiki import WikiPage, IWikiChangeListener
class TestWikiChangeListener(Component):
implements(IWikiChangeListener)
def __init__(self):
self.added = []
self.changed = []
self.deleted = []
self.deleted_version = []
self.renamed = []
def wiki_page_added(self, page):
self.added.append(page)
def wiki_page_changed(self, page, version, t, comment, author, ipnr):
self.changed.append((page, version, t, comment, author, ipnr))
def wiki_page_deleted(self, page):
self.deleted.append(page)
def wiki_page_version_deleted(self, page):
self.deleted_version.append(page)
def wiki_page_renamed(self, page, old_name):
self.renamed.append((page, old_name))
class WikiPageTestCase(unittest.TestCase):
def setUp(self):
self.env = EnvironmentStub()
self.env.path = tempfile.mkdtemp(prefix='trac-tempenv-')
def tearDown(self):
shutil.rmtree(self.env.path)
self.env.reset_db()
def test_new_page(self):
page = WikiPage(self.env)
self.assertFalse(page.exists)
self.assertIsNone(page.name)
self.assertEqual(0, page.version)
self.assertEqual('', page.text)
self.assertEqual(0, page.readonly)
self.assertEqual('', page.author)
self.assertEqual('', page.comment)
self.assertIsNone(page.time)
def test_existing_page(self):
t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage', 1, to_utimestamp(t), 'joe', '::1', 'Bla bla',
'Testing', 0))
page = WikiPage(self.env, 'TestPage')
self.assertTrue(page.exists)
self.assertEqual('TestPage', page.name)
self.assertEqual(1, page.version)
self.assertIsNone(page.resource.version) # FIXME: Intentional?
self.assertEqual('Bla bla', page.text)
self.assertEqual(0, page.readonly)
self.assertEqual('joe', page.author)
self.assertEqual('Testing', page.comment)
self.assertEqual(t, page.time)
history = list(page.get_history())
self.assertEqual(1, len(history))
self.assertEqual((1, t, 'joe', 'Testing', '::1'), history[0])
page = WikiPage(self.env, 'TestPage', 1)
self.assertEqual(1, page.resource.version)
self.assertEqual(1, page.version)
resource = Resource('wiki', 'TestPage')
page = WikiPage(self.env, resource, 1)
self.assertEqual(1, page.version)
def test_create_page(self):
page = WikiPage(self.env)
page.name = 'TestPage'
page.text = 'Bla bla'
t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
page.save('joe', 'Testing', '::1', t)
self.assertTrue(page.exists)
self.assertEqual(1, page.version)
self.assertEqual(1, page.resource.version)
self.assertEqual(0, page.readonly)
self.assertEqual('joe', page.author)
self.assertEqual('Testing', page.comment)
self.assertEqual(t, page.time)
self.assertEqual(
[(1, to_utimestamp(t), 'joe', '::1', 'Bla bla', 'Testing', 0)],
self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',)))
listener = TestWikiChangeListener(self.env)
self.assertEqual(page, listener.added[0])
def test_update_page(self):
t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc)
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage', 1, to_utimestamp(t), 'joe', '::1', 'Bla bla',
'Testing', 0))
page = WikiPage(self.env, 'TestPage')
page.text = 'Bla'
page.save('kate', 'Changing', '192.168.0.101', t2)
self.assertEqual(2, page.version)
self.assertEqual(2, page.resource.version)
self.assertEqual(0, page.readonly)
self.assertEqual('kate', page.author)
self.assertEqual('Changing', page.comment)
self.assertEqual(t2, page.time)
with self.env.db_query as db:
rows = db("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',))
self.assertEqual(2, len(rows))
self.assertEqual((1, to_utimestamp(t), 'joe', '::1', 'Bla bla',
'Testing', 0), rows[0])
self.assertEqual((2, to_utimestamp(t2), 'kate', '192.168.0.101',
'Bla', 'Changing', 0), rows[1])
listener = TestWikiChangeListener(self.env)
self.assertEqual((page, 2, t2, 'Changing', 'kate', '192.168.0.101'),
listener.changed[0])
page = WikiPage(self.env, 'TestPage')
history = list(page.get_history())
self.assertEqual(2, len(history))
self.assertEqual((2, t2, 'kate', 'Changing', '192.168.0.101'),
history[0])
self.assertEqual((1, t, 'joe', 'Testing', '::1'), history[1])
def test_delete_page(self):
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0))
page = WikiPage(self.env, 'TestPage')
page.delete()
self.assertFalse(page.exists)
self.assertEqual([], self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',)))
listener = TestWikiChangeListener(self.env)
self.assertEqual(page, listener.deleted[0])
def test_delete_page_version(self):
self.env.db_transaction.executemany(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
[('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0),
('TestPage', 2, 43, 'kate', '192.168.0.11', 'Bla', 'Changing', 0)])
page = WikiPage(self.env, 'TestPage')
page.delete(version=2)
self.assertTrue(page.exists)
self.assertEqual(
[(1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)],
self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',)))
listener = TestWikiChangeListener(self.env)
self.assertEqual(page, listener.deleted_version[0])
def test_delete_page_last_version(self):
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0))
page = WikiPage(self.env, 'TestPage')
page.delete(version=1)
self.assertFalse(page.exists)
self.assertEqual([], self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',)))
listener = TestWikiChangeListener(self.env)
self.assertEqual(page, listener.deleted[0])
def test_rename_page(self):
data = (1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage',) + data)
attachment = Attachment(self.env, 'wiki', 'TestPage')
attachment.insert('foo.txt', StringIO(), 0, 1)
page = WikiPage(self.env, 'TestPage')
page.rename('PageRenamed')
self.assertEqual('PageRenamed', page.name)
self.assertEqual('PageRenamed', page.resource.id)
self.assertEqual([data], self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('PageRenamed',)))
attachments = Attachment.select(self.env, 'wiki', 'PageRenamed')
self.assertEqual('foo.txt', attachments.next().filename)
self.assertRaises(StopIteration, attachments.next)
Attachment.delete_all(self.env, 'wiki', 'PageRenamed')
old_page = WikiPage(self.env, 'TestPage')
self.assertFalse(old_page.exists)
self.assertEqual([], self.env.db_query("""
SELECT version, time, author, ipnr, text, comment, readonly
FROM wiki WHERE name=%s
""", ('TestPage',)))
listener = TestWikiChangeListener(self.env)
self.assertEqual((page, 'TestPage'), listener.renamed[0])
def test_invalid_page_name(self):
invalid_names = ('../Page', 'Page/..', 'Page/////SubPage',
'Page/./SubPage', '/PagePrefix', 'PageSuffix/')
for name in invalid_names:
page = WikiPage(self.env)
page.name = name
page.text = 'Bla bla'
t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
self.assertRaises(TracError, page.save, 'joe', 'Testing', '::1', t)
page = WikiPage(self.env)
page.name = 'TestPage'
page.text = 'Bla bla'
t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
page.save('joe', 'Testing', '::1', t)
for name in invalid_names:
page = WikiPage(self.env, 'TestPage')
self.assertRaises(TracError, page.rename, name)
def test_invalid_version(self):
data = (1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)
self.env.db_transaction(
"INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
('TestPage',) + data)
self.assertRaises(ValueError, WikiPage, self.env,
'TestPage', '1abc')
resource = Resource('wiki', 'TestPage')
self.assertRaises(ValueError, WikiPage, self.env,
resource, '1abc')
resource = Resource('wiki', 'TestPage', '1abc')
page = WikiPage(self.env, resource)
self.assertEqual(1, page.version)
class WikiResourceChangeListenerTestCase(unittest.TestCase):
INITIAL_NAME = "Wiki page 1"
INITIAL_TEXT = "some text"
INITIAL_AUTHOR = "anAuthor"
INITIAL_COMMENT = "some comment"
INITIAL_REMOTE_ADDRESS = "::1"
def setUp(self):
self.env = EnvironmentStub(default_data=True)
self.listener = TestResourceChangeListener(self.env)
self.listener.resource_type = WikiPage
self.listener.callback = self.listener_callback
def tearDown(self):
self.env.reset_db()
def test_change_listener_created(self):
self._create_wiki_page(self.INITIAL_NAME)
self.assertEqual('created', self.listener.action)
self.assertTrue(isinstance(self.listener.resource, WikiPage))
self.assertEqual(self.INITIAL_NAME, self.wiki_name)
self.assertEqual(self.INITIAL_TEXT, self.wiki_text)
def test_change_listener_text_changed(self):
wiki_page = self._create_wiki_page(self.INITIAL_NAME)
CHANGED_TEXT = "some other text"
wiki_page.text = CHANGED_TEXT
wiki_page.save("author1", "renamed_comment", "::2")
self.assertEqual('changed', self.listener.action)
self.assertTrue(isinstance(self.listener.resource, WikiPage))
self.assertEqual(self.INITIAL_NAME, self.wiki_name)
self.assertEqual(CHANGED_TEXT, self.wiki_text)
self.assertEqual({"text":self.INITIAL_TEXT}, self.listener.old_values)
def test_change_listener_renamed(self):
wiki_page = self._create_wiki_page(self.INITIAL_NAME)
CHANGED_NAME = "NewWikiName"
wiki_page.rename(CHANGED_NAME)
self.assertEqual('changed', self.listener.action)
self.assertTrue(isinstance(self.listener.resource, WikiPage))
self.assertEqual(CHANGED_NAME, self.wiki_name)
self.assertEqual(self.INITIAL_TEXT, self.wiki_text)
self.assertEqual({"name":self.INITIAL_NAME}, self.listener.old_values)
def test_change_listener_deleted(self):
wiki_page = self._create_wiki_page(self.INITIAL_NAME)
wiki_page.delete()
self.assertEqual('deleted', self.listener.action)
self.assertTrue(isinstance(self.listener.resource, WikiPage))
self.assertEqual(self.INITIAL_NAME, self.wiki_name)
def _create_wiki_page(self, name=None):
name = name or self.INITIAL_NAME
wiki_page = WikiPage(self.env, name)
wiki_page.text = self.INITIAL_TEXT
wiki_page.save(
self.INITIAL_AUTHOR,
self.INITIAL_COMMENT,
self.INITIAL_REMOTE_ADDRESS)
return wiki_page
def listener_callback(self, action, resource, context, old_values = None):
self.wiki_name = resource.name
self.wiki_text = resource.text
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(WikiPageTestCase))
suite.addTest(unittest.makeSuite(WikiResourceChangeListenerTestCase))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='suite')