Adds puppet quick links to dropdown menu, implements views and adds tests. Converts index view to CBV.

This commit is contained in:
Johnny 2018-10-24 21:11:17 +00:00
parent 73456a3d8c
commit f083cf61c3
4 changed files with 65 additions and 18 deletions

View file

@ -41,13 +41,19 @@ folder and edit it to add/remove links to the menu.
{% block navbar_user %} {% block navbar_user %}
{% if account %} {% if account %}
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" id="user_options" aria-expanded="false">Logged in as {{user.username}} <span class="caret"></span></a> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" id="user_options" aria-expanded="false">
{% if puppet %}
Welcome, {{ puppet }}! <span class="text-muted">({{ account.username }})</span> <span class="caret"></span>
{% else %}
Logged in as {{ account.username }} <span class="caret"></span>
{% endif %}
</a>
<div class="dropdown-menu" aria-labelledby="user_options"> <div class="dropdown-menu" aria-labelledby="user_options">
<a class="dropdown-item" href="{% url 'character-create' %}">Create Character</a> <a class="dropdown-item" href="{% url 'character-create' %}">Create Character</a>
<a class="dropdown-item" href="{% url 'character-manage' %}">Manage Characters</a> <a class="dropdown-item" href="{% url 'character-manage' %}">Manage Characters</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
{% for character in account.characters|slice:"10" %} {% for character in account.characters|slice:"10" %}
<a class="dropdown-item" href="#">{{ character }}</a> <a class="dropdown-item" href="{{ character.web_get_puppet_url }}?next={{ request.path }}">{{ character }}</a>
{% empty %} {% empty %}
<a class="dropdown-item" href="#">No characters found!</a> <a class="dropdown-item" href="#">No characters found!</a>
{% endfor %} {% endfor %}

View file

@ -136,6 +136,29 @@ class CharacterCreateView(EvenniaWebTest):
# Make sure the character was actually created # Make sure the character was actually created
self.assertTrue(len(self.account.db._playable_characters) > 1, 'Account only has the following characters attributed to it: %s' % self.account.db._playable_characters) self.assertTrue(len(self.account.db._playable_characters) > 1, 'Account only has the following characters attributed to it: %s' % self.account.db._playable_characters)
class CharacterPuppetView(EvenniaWebTest):
url_name = 'character-puppet'
unauthenticated_response = 302
def get_kwargs(self):
return {
'pk': self.char1.pk,
'slug': slugify(self.char1.name)
}
def test_invalid_access(self):
"Account1 should not be able to puppet Account2:Char2"
# Login account
self.login()
# Try to access puppet page for char2
kwargs = {
'pk': self.char2.pk,
'slug': slugify(self.char2.name)
}
response = self.client.get(reverse(self.url_name, kwargs=kwargs), follow=True)
self.assertTrue(response.status_code >= 400, "Invalid access should return a 4xx code-- either obj not found or permission denied! (Returned %s)" % response.status_code)
class CharacterManageView(EvenniaWebTest): class CharacterManageView(EvenniaWebTest):
url_name = 'character-manage' url_name = 'character-manage'
unauthenticated_response = 302 unauthenticated_response = 302

View file

@ -9,7 +9,7 @@ from django import views as django_views
from evennia.web.website import views as website_views from evennia.web.website import views as website_views
urlpatterns = [ urlpatterns = [
url(r'^$', website_views.page_index, name="index"), url(r'^$', website_views.EvenniaIndexView.as_view(), name="index"),
url(r'^tbi/', website_views.to_be_implemented, name='to_be_implemented'), url(r'^tbi/', website_views.to_be_implemented, name='to_be_implemented'),
# User Authentication (makes login/logout url names available) # User Authentication (makes login/logout url names available)
@ -19,6 +19,7 @@ urlpatterns = [
# Character management # Character management
url(r'^characters/create/$', website_views.CharacterCreateView.as_view(), name="character-create"), url(r'^characters/create/$', website_views.CharacterCreateView.as_view(), name="character-create"),
url(r'^characters/manage/$', website_views.CharacterManageView.as_view(), name="character-manage"), url(r'^characters/manage/$', website_views.CharacterManageView.as_view(), name="character-manage"),
url(r'^characters/puppet/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', website_views.CharacterPuppetView.as_view(), name="character-puppet"),
url(r'^characters/update/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', website_views.CharacterUpdateView.as_view(), name="character-update"), url(r'^characters/update/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', website_views.CharacterUpdateView.as_view(), name="character-update"),
url(r'^characters/delete/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', website_views.CharacterDeleteView.as_view(), name="character-delete"), url(r'^characters/delete/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', website_views.CharacterDeleteView.as_view(), name="character-delete"),

View file

@ -15,8 +15,9 @@ from django.core.exceptions import PermissionDenied
from django.db.models.functions import Lower from django.db.models.functions import Lower
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404 from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse_lazy from django.urls import reverse, reverse_lazy
from django.views.generic import View, TemplateView, ListView, DetailView, FormView from django.views.generic import View, TemplateView, ListView, DetailView, FormView
from django.views.generic.base import RedirectView
from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic.edit import CreateView, UpdateView, DeleteView
from evennia import SESSION_HANDLER from evennia import SESSION_HANDLER
@ -102,20 +103,6 @@ def _gamestats():
return pagevars return pagevars
def page_index(request):
"""
Main root page.
"""
# handle webclient-website shared login
_shared_login(request)
# get game db stats
pagevars = _gamestats()
return render(request, 'index.html', pagevars)
def to_be_implemented(request): def to_be_implemented(request):
""" """
A notice letting the user know that this particular feature hasn't been A notice letting the user know that this particular feature hasn't been
@ -149,6 +136,20 @@ def admin_wrapper(request):
# Class-based views # Class-based views
# #
class EvenniaIndexView(TemplateView):
# Display this HTML page
template_name = 'website/index.html'
# Display these variables on it
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context object
context = super(EvenniaIndexView, self).get_context_data(**kwargs)
# Add game statistics and other pagevars
context.update(_gamestats())
return context
class EvenniaCreateView(CreateView): class EvenniaCreateView(CreateView):
@property @property
@ -324,6 +325,22 @@ class CharacterMixin(object):
# Return a queryset consisting of those characters # Return a queryset consisting of those characters
return self.model.objects.filter(id__in=ids).order_by(Lower('db_key')) return self.model.objects.filter(id__in=ids).order_by(Lower('db_key'))
class CharacterPuppetView(LoginRequiredMixin, CharacterMixin, RedirectView, ObjectDetailView):
def get_redirect_url(self, *args, **kwargs):
# Get the requested character, if it belongs to the authenticated user
char = self.get_object()
next = self.kwargs.get('next', reverse('character-manage'))
if char:
self.request.session['puppet'] = int(char.pk)
messages.success(self.request, "You become '%s'!" % char)
else:
self.request.session['puppet'] = None
messages.error(self.request, "You cannot become '%s'." % char)
return next
class CharacterManageView(LoginRequiredMixin, CharacterMixin, ListView): class CharacterManageView(LoginRequiredMixin, CharacterMixin, ListView):
paginate_by = 10 paginate_by = 10