import time from django.core.cache import cache from django.core.urlresolvers import reverse from django.test import TestCase from django.test.client import Client from django.http import HttpRequest from django.contrib.auth.models import User, AnonymousUser from markupwiki.models import Article, ArticleVersion, PUBLIC, LOCKED, DELETED from markupwiki import models from markupwiki.utils import make_wiki_links, wikify_markup_wrapper from markupwiki import views class ArticleTests(TestCase): def test_display_title(self): a = Article(title='section/name_with_spaces') self.assertEquals(a.display_title, 'name with spaces') def test_section_name(self): a = Article(title='section/name_with_spaces') self.assertEquals(a.section_name, 'section') def test_is_editable_by_user(self): public_article = Article(title='public', status=PUBLIC) locked_article = Article(title='locked', status=LOCKED) deleted_article = Article(title='deleted', status=DELETED) user = User(is_staff=False) staff_user = User(is_staff=True) anon_user = AnonymousUser() # check that anonymous users cannot edit self.assertFalse(public_article.is_editable_by_user(anon_user)) self.assertFalse(locked_article.is_editable_by_user(anon_user)) self.assertFalse(deleted_article.is_editable_by_user(anon_user)) # check that user can only edit public articles self.assert_(public_article.is_editable_by_user(user)) self.assertFalse(locked_article.is_editable_by_user(user)) self.assertFalse(deleted_article.is_editable_by_user(user)) # check that staff can edit any article self.assert_(locked_article.is_editable_by_user(staff_user)) self.assert_(deleted_article.is_editable_by_user(staff_user)) models.WRITE_LOCK_SECONDS = 1 class ArticleWriteLockTests(TestCase): alice = User(id=1, username='alice') bob = User(id=2, username='bob') article = Article(id=1, title='locktest') def setUp(self): cache.clear() def test_simple_lock(self): ''' test that bob can't grab the lock immediately after alice does ''' alice_initial_lock = self.article.get_write_lock(self.alice) bob_immediate_lock = self.article.get_write_lock(self.bob) alice_retained_lock = self.article.get_write_lock(self.alice) self.assertTrue(alice_initial_lock) self.assertFalse(bob_immediate_lock) self.assertTrue(alice_retained_lock) def test_lock_timeout(self): ''' test that the lock times out properly ''' alice_initial_lock = self.article.get_write_lock(self.alice) time.sleep(2) bob_wait_lock = self.article.get_write_lock(self.bob) self.assertTrue(alice_initial_lock) self.assertTrue(bob_wait_lock) def test_lock_release(self): ''' test that lock is released properly ''' alice_initial_lock = self.article.get_write_lock(self.alice) alice_release_lock = self.article.get_write_lock(self.alice, release=True) bob_immediate_lock = self.article.get_write_lock(self.bob) self.assertTrue(alice_initial_lock) self.assertTrue(alice_release_lock) self.assertTrue(bob_immediate_lock) def test_release_on_acquire(self): ''' test that if release is True on acquire lock is not set ''' alice_initial_lock = self.article.get_write_lock(self.alice, release=True) bob_immediate_lock = self.article.get_write_lock(self.bob) self.assertTrue(alice_initial_lock) self.assertTrue(bob_immediate_lock) class WikifyTests(TestCase): urls = 'markupwiki.urls' def _get_url(self, link, name=None): return '%s' % (reverse('view_article', args=[link]), name or link) def test_make_wiki_links_simple(self): result = make_wiki_links('[[test]]') self.assertEquals(result, self._get_url('test')) result = make_wiki_links('[[two words ]]') self.assertEquals(result, self._get_url('two words')) result_ws = make_wiki_links('[[ test ]]') self.assertEquals(result_ws, self._get_url('test')) def test_make_wiki_links_named(self): result = make_wiki_links('[[test|this link has a name]]') self.assertEquals(result, self._get_url('test', 'this link has a name')) def test_wikify_markup_wrapper(self): wrapped_upper_filter = wikify_markup_wrapper(lambda text: text.upper()) result = wrapped_upper_filter('[[test]]') self.assertEquals(result, self._get_url('TEST')) def test_wikify_markup_wrapper_double_wrap(self): ''' ensure that wrapped functions can't be double wrapped ''' wrapped_upper_filter = wikify_markup_wrapper(lambda text: text.upper()) self.assertEquals(wrapped_upper_filter, wikify_markup_wrapper(wrapped_upper_filter)) class ViewTestsBase(TestCase): urls = 'example.urls' def setUp(self): self.admin = User.objects.create_superuser('admin', 'admin@admin.com', 'password') self.frank = User.objects.create_user('frank', 'frank@example.com', 'password') self.test_article = Article.objects.create(title='test', creator=self.admin) ArticleVersion.objects.create(article=self.test_article, author=self.admin, number=0, body='this is a test') ArticleVersion.objects.create(article=self.test_article, author=self.frank, number=1, body='this is an update') ArticleVersion.objects.create(article=self.test_article, author=self.frank, number=2, body='this is the final update') # article with space in title self.two_word_article = Article.objects.create(title='two_words', creator=self.admin) ArticleVersion.objects.create(article=self.two_word_article, author=self.frank, number=0, body='this article title has a space') # locked article self.locked = Article.objects.create(title='locked', creator=self.admin, status=LOCKED) ArticleVersion.objects.create(article=self.locked, author=self.frank, number=0, body='lockdown') # clear cache at start of every test cache.clear() def login_as_user(self): self.client.login(username='frank', password='password') def login_as_admin(self): self.client.login(username='admin', password='password') class ViewArticleTests(ViewTestsBase): def test_normal(self): ''' test accessing an article without a version specified ''' resp = self.client.get('/wiki/test/') self.assertContains(resp, 'this is the final update') def test_specific_version(self): ''' test accessing a specific version of an article ''' resp = self.client.get('/wiki/test/history/1/') self.assertContains(resp, 'this is an update') def test_name_with_spaces(self): ''' test that a name with spaces is properly converted into a name with underscores ''' resp = self.client.get('/wiki/two words/') self.assertRedirects(resp, '/wiki/two_words/', status_code=301) def test_redirect(self): ''' test that a 302 is given for any article with a redirect_to ''' redirect = Article.objects.create(title='redirect', creator=self.admin, redirect_to=self.test_article) resp = self.client.get('/wiki/redirect/') self.assertRedirects(resp, '/wiki/test/', status_code=302) def test_missing_edit(self): ''' test that a 302 is given to the edit page if CREATE_MISSING_ARTICLE is True ''' views.CREATE_MISSING_ARTICLE = True self.login_as_user() resp = self.client.get('/wiki/newpage/') self.assertRedirects(resp, '/wiki/newpage/edit/', status_code=302) def test_missing_404(self): ''' test that a 404 is given if CREATE_MISSING_ARTICLE is False ''' views.CREATE_MISSING_ARTICLE = False self.login_as_user() resp = self.client.get('/wiki/newpage/') self.assertContains(resp, '', status_code=404) def test_staff_forms(self): ''' ensure that only admins can see the admin form ''' # make sure a normal user doesn't see the admin form self.login_as_user() resp = self.client.get('/wiki/test/') self.assertNotContains(resp, '