Compare commits

...

3 Commits

8 changed files with 252 additions and 10 deletions

View File

@ -859,6 +859,18 @@ Welcome to the wiki page!
start_date=timezone.now(), start_date=timezone.now(),
role=settings.SITH_CLUB_ROLES_ID["Board member"], role=settings.SITH_CLUB_ROLES_ID["Board member"],
).save() ).save()
# Adding user tutu
tutu = User(
username="tutu",
last_name="Tu",
first_name="Tu",
email="tutu@git.an",
date_of_birth="1942-06-12",
)
tutu.set_password("plop")
tutu.save()
tutu.groups = [settings.SITH_GROUP_PEDAGOGY_ADMIN_ID]
tutu.save()
# Adding subscription for sli # Adding subscription for sli
s = Subscription( s = Subscription(
@ -897,6 +909,18 @@ Welcome to the wiki page!
start=s.subscription_start, start=s.subscription_start,
) )
s.save() s.save()
# Tutu
s = Subscription(
member=tutu,
subscription_type=default_subscription,
payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0][0],
)
s.subscription_start = s.compute_start()
s.subscription_end = s.compute_end(
duration=settings.SITH_SUBSCRIPTIONS[s.subscription_type]["duration"],
start=s.subscription_start,
)
s.save()
Selling( Selling(
label=dcons.name, label=dcons.name,

View File

@ -27,7 +27,7 @@ from django import forms
from core.views.forms import MarkdownInput from core.views.forms import MarkdownInput
from core.models import User from core.models import User
from pedagogy.models import UV from pedagogy.models import UV, UVComment
class UVForm(forms.ModelForm): class UVForm(forms.ModelForm):
@ -68,3 +68,13 @@ class UVForm(forms.ModelForm):
super(UVForm, self).__init__(*args, **kwargs) super(UVForm, self).__init__(*args, **kwargs)
self.fields["author"].queryset = User.objects.filter(id=author_id).all() self.fields["author"].queryset = User.objects.filter(id=author_id).all()
self.fields["author"].initial = author_id self.fields["author"].initial = author_id
class UVCommentForm(forms.ModelForm):
"""
Form handeling creation and edit of an UVComment
"""
class Meta:
model = UVComment
fields = ()

View File

@ -44,8 +44,14 @@ class UV(models.Model):
return user.is_in_group(settings.SITH_GROUP_PEDAGOGY_ADMIN_ID) return user.is_in_group(settings.SITH_GROUP_PEDAGOGY_ADMIN_ID)
def can_be_viewed_by(self, user): def can_be_viewed_by(self, user):
"""
Only visible by subscribers
"""
return user.is_subscribed return user.is_subscribed
def __str__(self):
return self.code
code = models.CharField( code = models.CharField(
_("code"), _("code"),
max_length=10, max_length=10,

View File

@ -6,7 +6,18 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if can_create_uv(user) %}
<p>
<a href="{{ url('pedagogy:uv_create') }}">{% trans %}Create UV{% endtrans %}</a>
</p>
{% endif %}
{% for uv in object_list %} {% for uv in object_list %}
{{ uv.code }} <p>
{{ uv.code }}
{% if user.is_owner(uv) -%}
<a href="{{ url('pedagogy:uv_update', uv_id=uv.id) }}">{% trans %}Edit{% endtrans %}</a>
<a href="{{ url('pedagogy:uv_delete', uv_id=uv.id) }}">{% trans %}Delete{% endtrans %}</a>
{%- endif -%}
</p>
{% endfor %} {% endfor %}
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,13 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}UV Details{% endtrans %}
{% endblock %}
{% block content %}
<h1>{{ object.code }} - {{ object.title }}</h1>
<p>{{ object.objectives|markdown }}</p>
<p>{{ object.program|markdown }}</p>
<p>{{ object.skills|markdown }}</p>
<p>{{ object.key_concepts|markdown }}</p>
{% endblock %}

View File

@ -23,5 +23,121 @@
# #
from django.test import TestCase from django.test import TestCase
from django.core.urlresolvers import reverse
from django.core.management import call_command
# Create your tests here. from core.models import User
from pedagogy.models import UV
class UVCreation(TestCase):
"""
Test uv creation
"""
def setUp(self):
call_command("populate")
self.bibou = User.objects.filter(username="root").first()
self.tutu = User.objects.filter(username="tutu").first()
self.sli = User.objects.filter(username="sli").first()
self.guy = User.objects.filter(username="guy").first()
@staticmethod
def create_uv_template(user_id, code="IFC1", exclude_list=[]):
uv = {
"code": code,
"author": user_id,
"credit_type": "TM",
"semester": "SPRING",
"language": "FR",
"credits": 3,
"hours_CM": 10,
"hours_TD": 28,
"hours_TP": 0,
"hours_THE": 37,
"hours_TE": 0,
"manager": "Gilles BERTRAND",
"title": "Algorithmique et programmation : niveau I, initiés - partie I",
"objectives": """* Introduction à l'algorithmique et à la programmation pour initiés.
* Pratiques et développement en langage C.""",
"program": """* Découverte des outils élémentaires utilisés pour écrire, compiler et exécuter un programme écrit en langage C
* Règles de programmation : normes en cours, règles de présentation du code, commentaires
* Initiation à l'algorithmique et découverte des bases du langage C :
* les conditions
* les boucles
* les types de données
* les tableaux à une dimension
* manipulations des chaînes de caractères
* les fonctions et procédures""",
"skills": "* D'écrire un algorithme et de l'implémenter en C",
"key_concepts": """* Algorithme
* Variables scalaires et vectorielles
* Structures alternatives, répétitives
* Fonctions, procédures
* Chaînes de caractères""",
}
for excluded in exclude_list:
uv.pop(excluded)
return uv
def test_create_uv_admin_success(self):
self.client.login(username="root", password="plop")
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(self.bibou.id)
)
self.assertEquals(response.status_code, 302)
self.assertTrue(UV.objects.filter(code="IFC1").exists())
def test_create_uv_pedagogy_admin_success(self):
self.client.login(username="tutu", password="plop")
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(self.tutu.id)
)
self.assertEquals(response.status_code, 302)
self.assertTrue(UV.objects.filter(code="IFC1").exists())
def test_create_uv_unauthorized_fail(self):
# Test with anonymous user
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(0)
)
self.assertEquals(response.status_code, 403)
# Test with subscribed user
self.client.login(username="sli", password="plop")
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(self.sli.id)
)
self.assertEquals(response.status_code, 403)
# Test with non subscribed user
self.client.login(username="guy", password="plop")
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(self.guy.id)
)
self.assertEquals(response.status_code, 403)
# Check that the UV has never been created
self.assertFalse(UV.objects.filter(code="IFC1").exists())
def test_create_uv_bad_request_fail(self):
self.client.login(username="tutu", password="plop")
# Test with wrong user id (if someone cheats on the hidden input)
response = self.client.post(
reverse("pedagogy:uv_create"), self.create_uv_template(self.bibou.id)
)
self.assertNotEquals(response.status_code, 302)
self.assertEquals(response.status_code, 200)
# Remove a required field
response = self.client.post(
reverse("pedagogy:uv_create"),
self.create_uv_template(self.tutu.id, exclude_list=["title"]),
)
self.assertNotEquals(response.status_code, 302)
self.assertEquals(response.status_code, 200)
# Check that the UV hase never been created
self.assertFalse(UV.objects.filter(code="IFC1").exists())

View File

@ -46,6 +46,7 @@ urlpatterns = [
# Administration : Create Update Delete Edit # Administration : Create Update Delete Edit
url(r"^uv/create$", UVCreateView.as_view(), name="uv_create"), url(r"^uv/create$", UVCreateView.as_view(), name="uv_create"),
url(r"^uv/(?P<uv_id>[0-9]+)/delete$", UVDeleteView.as_view(), name="uv_delete"), url(r"^uv/(?P<uv_id>[0-9]+)/delete$", UVDeleteView.as_view(), name="uv_delete"),
url(r"^uv/(?P<uv_id>[0-9]+)/edit$", UVUpdateView.as_view(), name="uv_update"),
url( url(
r"^department/create$", r"^department/create$",
EducationDepartmentCreateView.as_view(), EducationDepartmentCreateView.as_view(),

View File

@ -22,7 +22,15 @@
# #
# #
from django.views.generic import CreateView, DeleteView, DetailView, ListView, FormView from django.views.generic import (
CreateView,
DeleteView,
DetailView,
UpdateView,
ListView,
FormView,
View,
)
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from core.views import ( from core.views import (
@ -33,17 +41,46 @@ from core.views import (
CanEditPropMixin, CanEditPropMixin,
) )
from pedagogy.forms import UVForm from pedagogy.forms import UVForm, UVCommentForm
from pedagogy.models import UV from pedagogy.models import UV
# Some mixins
class UVDetailFormView(DetailFormView):
class CanCreateUVFunctionMixin(View):
"""
Add the function can_create_uv(user) into the template
"""
@staticmethod
def can_create_uv(user):
"""
Creates a dummy instance of UV and test is_owner
"""
return user.is_owner(UV())
def get_context_data(self, **kwargs):
"""
Pass the function to the template
"""
kwargs = super(CanCreateUVFunctionMixin, self).get_context_data(**kwargs)
kwargs["can_create_uv"] = self.can_create_uv
return kwargs
# Acutal views
class UVDetailFormView(CanViewMixin, CanCreateUVFunctionMixin, DetailFormView):
""" """
Dispaly every comment of an UV and detailed infos about it Dispaly every comment of an UV and detailed infos about it
Allow to comment the UV Allow to comment the UV
""" """
pass model = UV
pk_url_kwarg = "uv_id"
template_name = "pedagogy/uv_detail.jinja"
form_class = UVCommentForm
class UVCommentDetailView(DetailView): class UVCommentDetailView(DetailView):
@ -54,7 +91,7 @@ class UVCommentDetailView(DetailView):
pass pass
class UVListView(CanViewMixin, ListView): class UVListView(CanViewMixin, CanCreateUVFunctionMixin, ListView):
""" """
UV guide main page UV guide main page
""" """
@ -108,12 +145,36 @@ class UVCreateView(CanCreateMixin, CreateView):
return reverse_lazy("pedagogy:uv_detail", kwargs={"uv_id": self.object.id}) return reverse_lazy("pedagogy:uv_detail", kwargs={"uv_id": self.object.id})
class UVDeleteView(DeleteView): class UVDeleteView(CanEditPropMixin, DeleteView):
""" """
Allow to delete an UV (Privileged) Allow to delete an UV (Privileged)
""" """
pass model = UV
pk_url_kwarg = "uv_id"
template_name = "core/delete_confirm.jinja"
def get_success_url(self):
return reverse_lazy("pedagogy:guide")
class UVUpdateView(CanEditPropMixin, UpdateView):
"""
Allow to edit an UV (Privilegied)
"""
model = UV
form_class = UVForm
pk_url_kwarg = "uv_id"
template_name = "core/edit.jinja"
def get_form_kwargs(self):
kwargs = super(UVUpdateView, self).get_form_kwargs()
kwargs["author_id"] = self.request.user.id
return kwargs
def get_success_url(self):
return reverse_lazy("pedagogy:uv_detail", kwargs={"uv_id": self.object.id})
class EducationDepartmentCreateView(CreateView): class EducationDepartmentCreateView(CreateView):