mirror of
https://github.com/ae-utbm/sith.git
synced 2024-12-22 07:41:14 +00:00
Fix wiki, plus clean up and add tests
This commit is contained in:
parent
8753e020a1
commit
9a9541088d
1
core/fixtures/pages.json
Normal file
1
core/fixtures/pages.json
Normal file
@ -0,0 +1 @@
|
||||
[{"model": "core.page", "pk": 1, "fields": {"title": "TROLL", "full_name": "guy2", "content": "ZZZZZZZZZZZZZZZZZZZZZ", "name": "guy2", "parent": null, "revision": 1, "is_locked": false}}, {"model": "core.page", "pk": 2, "fields": {"title": "Bibou", "full_name": "guy/bibou", "content": "Bibou Troll", "name": "bibou", "parent": 4, "revision": 1, "is_locked": false}}, {"model": "core.page", "pk": 3, "fields": {"title": "Troll", "full_name": "guy/bibou/troll", "content": "blbbllblbl", "name": "troll", "parent": 2, "revision": 1, "is_locked": false}}, {"model": "core.page", "pk": 4, "fields": {"title": "TROLL", "full_name": "guy", "content": "", "name": "guy", "parent": null, "revision": 1, "is_locked": false}}, {"model": "core.page", "pk": 5, "fields": {"title": "Bibou", "full_name": "bibou", "content": "", "name": "bibou", "parent": null, "revision": 1, "is_locked": false}}, {"model": "core.page", "pk": 6, "fields": {"title": "Bibou-Guy", "full_name": "bibou/guy", "content": "Bwahahahahahaha", "name": "guy", "parent": 5, "revision": 1, "is_locked": false}}]
|
19
core/migrations/0002_page_full_name.py
Normal file
19
core/migrations/0002_page_full_name.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='page',
|
||||
name='full_name',
|
||||
field=models.CharField(blank=True, verbose_name='page name', max_length=255),
|
||||
),
|
||||
]
|
@ -109,12 +109,25 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||
|
||||
|
||||
class Page(models.Model):
|
||||
"""
|
||||
The page class to build a Wiki
|
||||
Each page may have a parent and it's URL is of the form my.site/page/<grd_pa>/<parent>/<mypage>
|
||||
It has an ID field, but don't use it, since it's only there for DB part, and because compound primary key is
|
||||
awkward!
|
||||
Prefere querying pages with Page.get_page_by_full_name()
|
||||
|
||||
Be careful with the full_name attribute: this field may not be valid until you call save(). It's made for fast
|
||||
query, but don't rely on it when playing with a Page object, use get_full_name() instead!
|
||||
"""
|
||||
name = models.CharField(_('page name'), max_length=30, blank=False)
|
||||
title = models.CharField(_("page title"), max_length=255, blank=True)
|
||||
content = models.TextField(_("page content"), blank=True)
|
||||
revision = models.PositiveIntegerField(_("current revision"), default=1)
|
||||
is_locked = models.BooleanField(_("page mutex"), default=False)
|
||||
parent = models.ForeignKey('self', related_name="children", null=True, blank=True, on_delete=models.SET_NULL)
|
||||
# Attention: this field may not be valid until you call save(). It's made for fast query, but don't rely on it when
|
||||
# playing with a Page object, use get_full_name() instead!
|
||||
full_name = models.CharField(_('page name'), max_length=255, blank=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('name', 'parent')
|
||||
@ -125,38 +138,43 @@ class Page(models.Model):
|
||||
|
||||
@staticmethod
|
||||
def get_page_by_full_name(name):
|
||||
parent_name = '/'.join(name.split('/')[:-1])
|
||||
name = name.split('/')[-1]
|
||||
if parent_name == "":
|
||||
qs = Page.objects.filter(name=name, parent=None)
|
||||
else:
|
||||
qs = Page.objects.filter(name=name, parent__name=parent_name)
|
||||
return qs.first()
|
||||
"""
|
||||
Quicker to get a page with that method rather than building the request every time
|
||||
"""
|
||||
return Page.objects.filter(full_name=name).first()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Page, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
This function maintains coherence between full_name, name, and parent.full_name
|
||||
Be careful modifying it, it could break the entire page table!
|
||||
|
||||
This function is mandatory since Django does not support compound primary key,
|
||||
otherwise, Page class would have had PRIMARY_KEY(name, parent)
|
||||
Cleans up only the name for the moment, but this can be used to make any treatment before saving the object
|
||||
"""
|
||||
if '/' in self.name:
|
||||
self.name = self.name.split('/')[-1]
|
||||
if Page.objects.exclude(pk=self.pk).filter(full_name=self.get_full_name()).exists():
|
||||
raise ValidationError(
|
||||
_('Duplicate page'),
|
||||
code='duplicate',
|
||||
)
|
||||
super(Page, self).clean()
|
||||
print("name: "+self.name)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.full_clean()
|
||||
# This reset the full_name just before saving to maintain a coherent field quicker for queries than the
|
||||
# recursive method
|
||||
self.full_name = self.get_full_name()
|
||||
super(Page, self).save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.get_full_name()
|
||||
|
||||
def get_full_name(self):
|
||||
"""
|
||||
Computes the real full_name of the page based on its name and its parent's name
|
||||
You can and must rely on this function when working on a page object that is not freshly fetched from the DB
|
||||
(For example when treating a Page object coming from a form)
|
||||
"""
|
||||
if self.parent is None:
|
||||
return self.name
|
||||
return '/'.join([self.parent.get_full_name(), self.name])
|
||||
|
@ -148,3 +148,64 @@ class UserRegistrationTest(SimpleTestCase):
|
||||
response = c.post(reverse('core:login'), {'username': 'gcarlier', 'password': 'guy'})
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue('LOGIN_FAIL' in str(response.content))
|
||||
|
||||
def test_create_page_ok(self):
|
||||
"""
|
||||
Should create a page correctly
|
||||
"""
|
||||
c = Client()
|
||||
response = c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '',
|
||||
'name': 'guy',
|
||||
'title': 'Guy',
|
||||
'Content': 'Guyéuyuyé',
|
||||
})
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue('PAGE_SAVED' in str(response.content))
|
||||
|
||||
def test_create_child_page_ok(self):
|
||||
"""
|
||||
Should create a page correctly
|
||||
"""
|
||||
c = Client()
|
||||
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '',
|
||||
'name': 'guy',
|
||||
'title': 'Guy',
|
||||
'Content': 'Guyéuyuyé',
|
||||
})
|
||||
response = c.post(reverse('core:page_edit', kwargs={'page_name': 'guy/bibou'}), {'parent': '1',
|
||||
'name': 'bibou',
|
||||
'title': 'Bibou',
|
||||
'Content':
|
||||
'Bibibibiblblblblblbouuuuuuuuu',
|
||||
})
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue('PAGE_SAVED' in str(response.content))
|
||||
|
||||
def test_access_child_page_ok(self):
|
||||
"""
|
||||
Should display a page correctly
|
||||
"""
|
||||
c = Client()
|
||||
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '',
|
||||
'name': 'guy',
|
||||
'title': 'Guy',
|
||||
'Content': 'Guyéuyuyé',
|
||||
})
|
||||
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy/bibou'}), {'parent': '1',
|
||||
'name': 'bibou',
|
||||
'title': 'Bibou',
|
||||
'Content':
|
||||
'Bibibibiblblblblblbouuuuuuuuu',
|
||||
})
|
||||
response = c.get(reverse('core:page', kwargs={'page_name': 'guy/bibou'}))
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue('PAGE_FOUND : Bibou' in str(response.content))
|
||||
|
||||
def test_access_page_not_found(self):
|
||||
"""
|
||||
Should not display a page correctly
|
||||
"""
|
||||
c = Client()
|
||||
response = c.get(reverse('core:page', kwargs={'page_name': 'swagg'}))
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue('PAGE_NOT_FOUND' in str(response.content))
|
||||
|
@ -64,12 +64,15 @@ def login(request):
|
||||
|
||||
def logout(request):
|
||||
"""
|
||||
The logout view:w
|
||||
The logout view
|
||||
"""
|
||||
auth_logout(request)
|
||||
return redirect('core:index')
|
||||
|
||||
def user(request, user_id=None):
|
||||
"""
|
||||
Display a user's profile
|
||||
"""
|
||||
context = {'title': 'View a user'}
|
||||
if user_id == None:
|
||||
context['user_list'] = User.objects.all
|
||||
@ -78,6 +81,9 @@ def user(request, user_id=None):
|
||||
return render(request, "core/user.html", context)
|
||||
|
||||
def user_edit(request, user_id=None):
|
||||
"""
|
||||
This view allows a user, or the allowed users to modify a profile
|
||||
"""
|
||||
user_id = int(user_id)
|
||||
context = {'title': 'Edit a user'}
|
||||
if user_id is not None:
|
||||
@ -88,6 +94,9 @@ def user_edit(request, user_id=None):
|
||||
return user(request, user_id)
|
||||
|
||||
def page(request, page_name=None):
|
||||
"""
|
||||
This view displays a page or the link to create it if 404
|
||||
"""
|
||||
context = {'title': 'View a Page'}
|
||||
if page_name == None:
|
||||
context['page_list'] = Page.objects.all
|
||||
@ -96,21 +105,30 @@ def page(request, page_name=None):
|
||||
if context['page'] is not None:
|
||||
context['view_page'] = True
|
||||
context['title'] = context['page'].title
|
||||
context['test'] = "PAGE_FOUND"
|
||||
context['tests'] = "PAGE_FOUND : "+context['page'].title
|
||||
else:
|
||||
context['title'] = "This page does not exist"
|
||||
context['new_page'] = page_name
|
||||
context['test'] = "PAGE_NOT_FOUND"
|
||||
context['tests'] = "PAGE_NOT_FOUND"
|
||||
return render(request, "core/page.html", context)
|
||||
|
||||
def page_edit(request, page_name=None):
|
||||
"""
|
||||
page_edit view, able to create a page, save modifications, and display the page ModelForm
|
||||
"""
|
||||
context = {'title': 'Edit a page',
|
||||
'page_name': page_name}
|
||||
p = Page.get_page_by_full_name(page_name)
|
||||
# New page
|
||||
if p == None:
|
||||
# TODO: guess page name by splitting on '/'
|
||||
# Same for the parent, try to guess
|
||||
p = Page(name=page_name)
|
||||
parent_name = '/'.join(page_name.split('/')[:-1])
|
||||
name = page_name.split('/')[-1]
|
||||
if parent_name == "":
|
||||
p = Page(name=name)
|
||||
else:
|
||||
parent = Page.get_page_by_full_name(parent_name)
|
||||
p = Page(name=name, parent=parent)
|
||||
# Saving page
|
||||
if request.method == 'POST':
|
||||
f = PageForm(request.POST, instance=p)
|
||||
if f.is_valid():
|
||||
@ -118,6 +136,7 @@ def page_edit(request, page_name=None):
|
||||
context['tests'] = "PAGE_SAVED"
|
||||
else:
|
||||
context['tests'] = "PAGE_NOT_SAVED"
|
||||
# Default: display the edit form without change
|
||||
else:
|
||||
context['tests'] = "POST_NOT_RECEIVED"
|
||||
f = PageForm(instance=p)
|
||||
|
Loading…
Reference in New Issue
Block a user